React unable to change default value

    const handleExperiences = (value, index, key) => {
        let user = localStorage.getItem('user')
        if (!user) return

        user = JSON.parse(user)

        if (key === 'ending_in') {
            if (value <= parseInt(experiences[index]['starting_from'])) {
                handleShowSnack('error', 'Ending should be greater than starting')
                return
            }
        }
        experiences[index][key] = value
        experiences[index]['user'] = user.id
        setExperiences(experiences)
    }

    const [experiences, setExperiences] = useState([
        {
            position: null,
            starting_from: null,
            ending_in: null,
            country: null,
            city: null
        }
    ])

    useEffect(() => {
        if (resume && resume.experiences) {
            setExperiences(resume.experiences)
            setSkills(resume.resume_skills)
        }
    }, [])


    return (
        <div>
            {experiences.map((exp, index) => (
            <>
                <Grid container className={classes.marginTop4} key={index}>
                    {index === 0 ? (
                        <Grid item md={12} sm={12} xs={12}>
                            <span className={classes.fieldLabel}>PRODUCTION EXPERIENCE</span>
                        </Grid>
                    ) : (
                        ''
                    )}

                    <Grid item md={6} sm={4} xs={12} className={smUp ? classes.paddingRight1 : ''}>
                        <span className={classes.fieldLabel}>Position</span>
                        <CustomTextField
                            variant="outlined"
                            name="position"
                            onChange={e => handleExperiences(e.target.value, index, 'position')}
                            type="text"
                            fullWidth
                            placeholder=""
                            value={exp.position}
                        />
                    </Grid>
                    <Grid item md={3} sm={4} xs={12} className={smUp ? clsx(classes.paddingLeft1, classes.paddingRight1) : ''}>
                        <span className={classes.fieldLabel}>Starting from</span>
                        <Selector
                            options={years}
                            selectedOption={selectedStart}
                            setSelectedOption={setSelectedStart}
                            backColor="transparent"
                            // setValue={setSelectedStart}
                            setValue={e => handleExperiences(e.value, index, 'starting_from')}
                            value={exp.starting_from}
                        />
                    </Grid>
                    <Grid item md={3} sm={4} xs={12} className={smUp ? classes.paddingLeft1 : ''}>
                        <span className={classes.fieldLabel}>Ending in</span>
                        <Selector
                            options={years}
                            selectedOption={selectedEnd}
                            setSelectedOption={setSelectedEnd}
                            backColor="transparent"
                            setValue={e => handleExperiences(e.value, index, 'ending_in')}
                            value={exp.ending_in}
                        />
                    </Grid>
                </Grid>
                <Grid container className={classes.marginTop2}>
                    <Grid item md={6} sm={6} xs={12} className={smUp ? classes.paddingRight1 : ''}>
                        <span className={classes.fieldLabel}>Country</span>
                        <Selector
                            options={countries}
                            selectedOption={selectedCountry}
                            setSelectedOption={setSelectedCountry}
                            backColor="transparent"
                            setValue={e => handleExperiences(e.value, index, 'country')}
                            value={exp.country}
                        />
                    </Grid>
                    <Grid item md={6} sm={6} xs={12} className={smUp ? classes.paddingLeft1 : ''}>
                        <span className={classes.fieldLabel}>City</span>
                        {/* <Selector
                    options={cities}
                    selectedOption={selectedCity}
                    setSelectedOption={setSelectedCity}
                    backColor="transparent"
                /> */}
                        <CustomTextField
                            variant="outlined"
                            type="text"
                            fullWidth
                            placeholder="City"
                            onChange={e => handleExperiences(e.target.value, index, 'city')}
                            value={exp.city}
                        />
                    </Grid>
                </Grid>
            </>
        ))}
        </div>
    )

Here i am using react hooks state

Here, I am trying to change the default value which coming from api. But, I am not able to change on onChange method .

I am looping the dynamic input fields. and chnaging them on onchange method so that i can update new data

Please take a look how can i handle this .

Or any other way to handle this problem

Thanks

Upvotes: 1

Views: 43

Answers (1)

Drew Reese
Drew Reese

Reputation: 202846

You are mutating your experiences state value in the handleExperiences callback.

const handleExperiences = (value, index, key) => {
    let user = localStorage.getItem('user')
    if (!user) return

    user = JSON.parse(user)

    if (key === 'ending_in') {
        if (value <= parseInt(experiences[index]['starting_from'])) {
            handleShowSnack('error', 'Ending should be greater than starting')
            return
        }
    }
    experiences[index][key] = value      // <-- mutation!!
    experiences[index]['user'] = user.id // <-- mutation!!
    setExperiences(experiences)
}

You should always shallow copy state, and nested state, that you are updating.

const handleExperiences = (value, index, key) => {
  let user = localStorage.getItem('user');
  if (!user) return;

  user = JSON.parse(user);

  if (key === 'ending_in') {
    if (value <= parseInt(experiences[index]['starting_from'])) {
      handleShowSnack('error', 'Ending should be greater than starting');
      return;
    }
  }

  setExperiences(experiences => experiences.map(
    (el, i) => i === index 
      ? {
        ...el,
        [key]: value,
        user: user.id,
      }
      : el,
  ));
}

Upvotes: 1

Related Questions