Home » Javascript » javascript – React not re-rendering on changing array within state object

javascript – React not re-rendering on changing array within state object

Posted by: admin February 24, 2020 Leave a comment

Questions:

I have a state like this:

const [data, setData] = useState[{name:"abc", gender: "male", experience: ["a","b","c"]}];

I have a display function for experience

const display= () => {
  let items = data.experience;
  return items.map((val,ind) => {
    return(<li key={ind}>{val}</li>);
  });
}

If I delete a value of experience, my state changes with the new items array but my component is not updating with the updated items, how can I overcome this issue

Delete Function: (It is working perfectly and state changes, but component is not rerendering new state)

  const deleteExperience = (ind) => {
    let newData = data;
    let experiences = newData.experience.filter((val, id) => id !== ind);
    newData.experience = experiences;
    setData(newData);
  };
How to&Answers:

Try this- you can delete like this

export default function App() {
  const [data, setData] = React.useState({
    name: "abc",
    gender: "male",
    experience: ["a", "b", "c"]
  });
  const deleteIt = id => {
    let filtered = data.experience.filter(filt => filt !== id);
    setData({
      ...data,
      experience: filtered
    });
  };
  return (
    <div className="App">
      <ul>
        {data.experience.map(d => (
          <li key={d} onClick={() => deleteIt(d)}>
            <h3>{d}</h3>
          </li>
        ))}
      </ul>
    </div>
  );
}

Live working demo

Answer:

i’m not sure but your variable “items” is not used, maybe you want to do items.map ?

Answer:

How are you deleting the array? if you are using splice to delete an index.
This will happen sometimes that you call setState before that actual data change in array so try to call setState after a little delay to that operation like setTimeout

setTimeout(function(){
  // call your setState here with new data
}, 1000);

Answer:

I have fixed it, the issue was in delete function:

const deleteExperience = (ind) => { 
    let newData = data;
    let experiences = newData.experience.filter((val, id) => id !== ind); 
    newData.experience = experiences;
    setData(newData); 
};

Correction (object spread should be used) as = sign does not create a new array but creates a reference to the original array:

const deleteExperience = (ind) => { 
    let newData = {...data};
    let experiences = newData.experience.filter((val, id) => id !== ind); 
    newData.experience = experiences;
    setData(newData); 
};