4

I am using react-native-simple-store and have written the below function to update the property of a supplied object stored in an array of objects. To do so, I used the method mentioned in issue #31 for deleting items.

Trouble is since I'm using .push, updating an item causes it to be rendered at the bottom of the array. This causes items to move in the FlatList unnecessarily.

Is there a more efficient method for updating a property of an object within the array (without causing this issue using .push)?

plusProgress = (itemId, progress) => {
  const foods = this.state.foods.filter(({ id }) => itemId !== id);
    const updatedItem = {
      itemId,
      progress: progress + 1
    };
  foods.push(updatedItem);
  this.setState({ foods });
  store.save('foods', foods);
}
3
  • What is store? Commented Apr 13, 2018 at 14:51
  • store is a reference to an imported wrapper around AsyncStorage (from react-native-simple-store). Commented Apr 13, 2018 at 14:58
  • So this saves data more permanently in a database or file system? Commented Apr 13, 2018 at 14:59

3 Answers 3

5

Create a new array with the updated object in the correct position, then call setState() with that new array. Be sure to return the current item as-is if is not the one you are trying to update. Otherwise, array elements will be replaced by null

  plusProgress = (itemId, progress) => {

  const foods = this.state.foods.map(item => {
    if (item.itemId === itemId) {
      return Object.assign({}, item, {progress: progress + 1});
    } 
    return item      
  })

  this.setState({ foods: foods })
}
Sign up to request clarification or add additional context in comments.

6 Comments

I've read that changing values in state directly is not safe. Note that const foods is not a copy. It is a reference to the array from this.state.
Thanks @Code-Apprentice! I can't comment your solution. So, I rewritten my solution to fix a little bug in your code.
Awesome! Yes, that is the part I missed. I will just delete my answer then.
@Code-Apprentice thanks for the reply, when I run this function it removes the value assigned to progress: I.e. it goes from progress: 0 to progress: rather than to progress: 1
@garethiv What do you mean by progress:? Where do you see this? How is the function called? What is passed as the progress parameter? Is this parameter needed? Can you just use item.progress instead?
|
3

You may try not immutable adding to array

foods.concat(updatedItem);

More about mutating and non-mutating array methods here https://lorenstewart.me/2017/01/22/javascript-array-methods-mutating-vs-non-mutating/

Comments

0

Rather than deleting the object from the list, replace it with an updated version:

plusProgress = (itemId, progress) => {
    const foods = this.state.foods.map(food => {
        if (itemId === food.id) {
            return Object.assign({}, food, {progress: progress + 1});
        }

        return item;
    });

    this.setState({foods});
}

To be more accurate, you probably should remove the progress parameter from plusProgress() and use item.progress instead. This ensures that you increment the current progress value rather than rely on passing an unrelated value to the function.

4 Comments

Hi thanks for the reply, when I used this it changed my object's id to undefined forcing me to have to reset storage
@garethiv I might not have the code here exactly correct. The basic concept is sound, though: create a new array with the updated object in the correct position, then call setState() with that new array. I leave it to you to fill in the correct details and debug the code. Note that it is difficult to give a completely correct answer because you have not provided a complete definition of your component. I am inferring the shape of this.state from very limited information.
Gotcha, I'll have a tinker and see if I can crack it... this.state.foods is an array of objects, each object with 7 properties.
And one of those properties is id, correct? Double check that you copied the code from my answer correctly. I don't see any reason why this code should set the id to undefined. There may be a bug elsewhere in your code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.