简体   繁体   中英

React not re-rendering on changing array within state object

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);
  };

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

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);

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); 
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM