Search code examples
reactjscheckboxreact-hooksonchangeuse-state

Why my value of array is changing when I'm setting state of other object in react?


const [dataToAdd, setDataToAdd] = useState({
    name: '', gender: '', email: '', imgUrl: '', website: '', skills: ''
});

const handleEnrollClick = () => {
    console.log(skillsAdd.toString())
    setStudentData([...studentData, dataToAdd]);
    setDataToAdd({ name: '', gender: '', email: '', imgUrl: '', website: '', skills: '' });
}

const onChange = (e) => {
    setDataToAdd({ ...dataToAdd, [e.target.name]: e.target.value });
}

let skillsAdd = []
const onChangeRadio = (e) => {
    if (e.target.checked) {
        skillsAdd.push(e.target.value);
    } else if (!e.target.checked) {
        skillsAdd.splice(skillsAdd.indexOf(e.target.value), 1);
    }
    
    console.log(skillsAdd)
    // setDataToAdd({...dataToAdd, skills: skillsAdd.toString()});
}

There are 3 checkboxes, 'JAVA', 'HTML' and 'CSS'. The logic in 'if' and 'else if' adds and removes these values of checkboxes i.e 'JAVA', 'HTML' and 'CSS' in the array 'skillsAdd' which works perfectly fine. But when I'm setting the state of 'dataToAdd' by using function 'setDataToAdd' then the 'skillsAdd' array changes totally. Following is the output:

Output when 'setDataToAdd' is commented and all three checkboxes i.e 'JAVA', 'HTML' and 'CSS' are checked: ['java', 'html', 'css']

Output when 'setDataToAdd' is not commented and all three checkboxes i.e 'JAVA', 'HTML' and 'CSS' are checked: ['css']

When 'setDataToAdd' is written then it should only affect 'dataToAdd', but it is affecting 'skillsArray'. How is this possible ?


Solution

  • You need to maintain a separate state for skillsAdd and use it to update dataToAdd state.

    const [dataToAdd, setDataToAdd] = useState({
      name: "",
      gender: "",
      email: "",
      imgUrl: "",
      website: "",
      skills: "",
    });
    
    // Use state for skillsAdd array
    const [skillsAdd, setSkillsAdd] = [];
    
    const handleEnrollClick = () => {
      console.log(skillsAdd.toString());
      setStudentData([...studentData, dataToAdd]);
      setDataToAdd({
        name: "",
        gender: "",
        email: "",
        imgUrl: "",
        website: "",
        skills: "",
      });
    };
    
    const onChange = (e) => {
      setDataToAdd({ ...dataToAdd, [e.target.name]: e.target.value });
    };
    
    const onChangeRadio = (e) => {
      const tempSkillsArray = [...skillsAdd];
    
      if (e.target.checked) {
        tempSkillsArray.push(e.target.value);
      } else if (!e.target.checked) {
        tempSkillsArray.splice(tempSkillsArray.indexOf(e.target.value), 1);
      }
    
      // update the skillsAdd state
      setSkillsAdd(tempSkillsArray);
    
      // update dataToAdd using tempSkillsArray
      setDataToAdd({ ...dataToAdd, skills: tempSkillsArray.toString() });
    };
    
    // keep console log outside the onChangeRadio function
    console.log(skillsAdd);