1

I have this type of state in my app

state = {
  abc: true,
  array: [
    { id: 12345, done: false },
    { id: 10203, done: false },
    { id: 54321, done: false }
  ]
}; 

I am looking for a solution to the following problem: I need to change done property accordingly to passed id like in the following function when something like this handle(12345) is passed as an argument to handle function :

  handle = id => {
  this.state.array.map(e => {
    if (e.key === id) {
      this.setState({array: [
        { id: id, done: true },
        { id: 10203, done: false },
        { id: 54321, done: false }
      ]})
    }
  });
};

In simple words I need to change just one object in array based on provided id.

Thanks for any help or tips!

1

4 Answers 4

4

I'd write the handle method as:

handle = id => {
  this.setState(prevState => {
    const { array } = prevState;
    return {
      array: [
        ...array.filter(o => o.id !== id),
        {id, done: true}
      ]
    };
  });
};

The idea here is that, remove the matching id from old state, and then add a new object to the array with id and done property as {id, done: true}.

Sign up to request clarification or add additional context in comments.

1 Comment

This also changes the order of the array elements though
3

Once you are allowed to restructure state to be hashmap instead of array:

state = {
  abc: true,
  array: {
    12345: { done: false },
    10203: { done: false },
    54321: { done: false }
  ]
}; 

then you will be able to use power of spread operator:

let id = 12345;
this.setState({
    array: {
        ...this.state.array,
        [id]: {
            ...this.state.array[id], 
            done: true
        }
    }
});

Otherwise using array.map() seems to be the only option

Comments

1

You can use this Redux pattern to return a new array with the element in question being changed, while keeping your array immutable:

handle = id => {
  const updatedArray = this.state.array.map(e => {
    if (e.key === id) {
      return { id: id, done: true };
    }
    else {
      return e;
    }
  });
  this.setState({array: updatedArray});
};

This keeps your data structures immutable while changing only what you need to change.

Comments

0
var newArray = this.state.array;
  for(var i = 0; i < newArray.length; i++){
      if(newArray[i].id === 12345) {
        newArray[i].done = true;
      }
  }

  this.setState({array: newArray});

By creating the newArray here you will be avoiding directly touching the state element, so you can change anything you want inside it afterwards you can set the state.

2 Comments

Are you still using for loop ? :)
Hi @ArupRakshit I wanted to simplify it for our friend, since the question he was asking is rather simple, so I assumed there is a possibility he is a beginner, this way it'd be easier for him to understand. Fortunately I am not here to boast about my skills or undermine others. Have a good day.

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.