1

I have jsfiddle Link https://jsfiddle.net/ilikeflex/r2uws1ez/30/

I am trying to set new state by accessing the previous state. I have three different cases where i am trying to update the state but i am not sure why does Case2 and Case 3 does not work. Can you please help me ??

const useState = React.useState;

function Example() {
  
  const [todos, setTodos] = useState([
    {id:1,text:'Learn React'},
    {id:2,text:'Learn TypeScript'},
    {id:3,text:'Learn Java'}
    ]);  
    
  const case1 = () => {
   const newItem = {id:3,text:'Learn C++'};
   
   setTodos((prevState) => {
    return prevState.concat(newItem);
   });
  
  }  
  
  const case2 = () => {
   const newItem = {id:3,text:'Learn .Net'};
   
   setTodos((prevState) => {
    prevState.push(newItem);  // I am adding to previous state and returning it
    return prevState;
   });
  
  }  
  
 const case3 = () => {
   const newItem = {id:3,text:'Learn C#'};
   
   setTodos((prevState) => {
    let result = { ...prevState, newItem }; // using spread operator
    return result;
   });
  
  }
  
  return (
    <div>

      <button onClick={case1}>Case 1</button>
      <button onClick={case2}>Case 2</button>
      <button onClick={case3}>Case 3</button>
      

      <ul>
            {todos.map((item) => (
            <li key={item.id}>{item.text}</li>
          ))}
      </ul>    
    </div>
  );
}

ReactDOM.render(<Example />, document.getElementById('root'))

2 Answers 2

3

To make case 2 work, you need to make a variable out of the prevState first. Then you can push to it and return that new variable.

const case2 = () => {
   const newItem = {id:3,text:'Learn .Net'};
   
   setTodos((prevState) => {
   const newState = [...prevState]
    newState.push(newItem);
    return newState;
   });
  
  }  

For case 3, you made a little mistake by making result an object instead of an array. Change the {} to [] and it should work fine, like this.

const case3 = () => {
   const newItem = {id:3,text:'Learn C#'};
   
   setTodos((prevState) => {
    let result = [...prevState, newItem ] ;
    return result;
   });
  
  }
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you Aron for making Case 2 and Case 3 work. But in Case 2 why i need to create a new variable. In case 1 also i am not making new variable.
@Raj .concat(value) returns a new array with the value added to it. But .push(value) changes the existing array and does not return a new array.
@Aron Make sense. It is always new array need to be created
-1

In all the cases, a new array need be to created and returned.

Case 1.

return prevState.concat(newItem); [ concat create a new array ]

Case 2

const newState = [...prevState];  [ Spread Operator creates a new array ] 
    newState.push(newItem);
    return newState;

Case 3

 let result = [...prevState, newItem ] ; [ Spread Operator creates a new array and newItem is added simultaneously ]
    return result;

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

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.