简体   繁体   中英

Updating item by react useState hook

I am new to functional components in react and I have a problem with updating data. Here is my function that just sets actual data to a variable, finds the actual item and updates it. The problem is that finds the actual item correctly but doesn't update the data. Data is just useState with an array of elements of course.

  const onEditElement = (elementId) => {
    let elements = data;
    let actualElement = elements.find((x) => x.id === elementId);
    actualElement = { value: "newValue" };
    setData(elements);
};

this is how data looks like:

const [data, setData] = useState([{id: 1, value: "initial"}]);

How can I solve this problem and what is causing it?

You are trying to update the elements array by changing the found object in the onEditElement() function that this code doesn't work (read the mistake parts below to find out why this happening).

you should change the function like this:

const onEditElement = (elementId) => {
  let elements = [...data];
  let currentElementIndex = elements.findIndex((x) => x.id === elementId);
  if (currentElementIndex === -1) return;
  elements[currentElementIndex] = { id: elementId, value: "newValue" };
  // if you do elements[currentElementIndex].value = ... your data array will be mutated. then its better you do the way above
  setData(elements);
};

Description

  1. Generally: in the React Class Component we were defining a state and we were updating that state using setState({ key: value }) . in the React Functional Component we have a different approach. we can have multiple useState s and also we should update the whole thing when we use state setter. then, if we have { key1: value1, key2: value2 } and we want to change the key1's value. we should put { key1: newValue1, key2: value2 } in the state setter. we can do this with setData((prvData) => ({...prevData, key1: newValue1 }))
  2. Your Case: you have an array of objects. it does not matter you are using Class or Functional component. suppose you have an array in your this.state data key in the Class Component like this.state = { data: [] } . you should put whole array with updated items in the setState function like setState({ data: WHOLE_ARRAY_WITH_UPDATED_ITEMS }) . also you should do this in Functional Component and do setData(WHOLE_ARRAY_WITH_UPDATED_ITEMS)

The Mistakes :

  1. you should use spread operator to prevent mutate the data array.
  2. you are defining new variable called actualElement and you are updating this variable and think it should change the elements array but it is an invidual object that has no connection to elements array. this variable is separated from elements array and changing it won't cause an effect on elements array. you should find actualElement index and update elements array directly using the current editing index somehow I did in the code above.

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