20

Thanks in advance. I have a state array as below.

I need to add an item to state array, I came across that we need not do state mutation. How do i set state with prevState.

const [messages, setMessages] = React.useState(
        [
            {
                _id: 12,
                createdAt: new Date(),
                text: 'All good',
                user: {
                    _id: 1,
                    name: 'Sian Pol',
                }
            },
            {
                _id: 21,
                createdAt: "2019-11-10 22:21",
                text: 'Hello user',
                user: {
                    _id: 2,
                    name: 'User New'
                }
            }]
    )

How to to i call the set State to append this state array.

Something like this?

setMessages(previousState => ({...stat

Can anyone help me in getting the above line code.

Ankit Jayaprakash
  • 1,040
  • 3
  • 15
  • 31
  • Does this answer your question? [Push method in React Hooks (useState)?](https://stackoverflow.com/questions/54676966/push-method-in-react-hooks-usestate) – Tolotra Raharison Nov 30 '19 at 16:15

5 Answers5

42

To insert new element at the end of the list

const addMessage = (newMessage) => setMessages(oldMessages => [...oldMessages, newMessage])

To insert new element at the begining of the list

const addMessage = (newMessage) => setMessages(oldMessages => [newMessage, ...oldMessages])
Tolotra Raharison
  • 3,034
  • 1
  • 10
  • 15
  • 1
    In my case, using push was an issue because I was returning the result from the push itself, which returns the new length of the array, not the array itself. `setSelectedList(prevState => prevState.push(val))` will set the state object to the length of the array, in other words. – Nate Kindrew May 05 '21 at 15:13
15

More readable and cleaner solution it would be:

Create a variable that holds a copy of the actual state:

If state is an array and you need to add an element in it

const newState = [...messages, 'Hi buddy'];
setMessages(newState);
 
or

setMessages(prevState => [...prevState, "Hi Buddy"]);

If state is an object and you need to update a property in it

const newState = Object.assign({}, message, {name: 'Michael Scott'});
setMessages(newState);

or

setMessages(prevState => {...prevState, name: "Michael Scott" });
Astrit Spanca
  • 643
  • 5
  • 13
1

Your state is an array so you will need to spread your previous state into a new array and add the new message using [...prevState, newMessage]

What you try to do is return an object, because {} is a code block so you need to wrap it inside () if you return an object which is what you are trying to do

setMessages(prevState => [...prevState, newMessage])
Asaf Aviv
  • 11,279
  • 1
  • 28
  • 45
1
setMessages(prevState => [...prevState, newMessage])
Pedram
  • 15,766
  • 10
  • 44
  • 73
Ankit Jayaprakash
  • 1,040
  • 3
  • 15
  • 31
0

There is no real need to use the prevState, you could just do:

setMessages([...messages, newMessage])
Konstantin
  • 1,390
  • 6
  • 18