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.

1

5 Answers 5

44

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])
Sign up to request clarification or add additional context in comments.

1 Comment

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.
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" });

4 Comments

I think this will mutate the state.
It will not for sure
@AnkitJayaprakash That is what the ...spread operator does, make a copy, thus no mutation happens
What are the consequences of one on another? Are both same performance wise?
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])

Comments

1
setMessages(prevState => [...prevState, newMessage])

Comments

0

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

setMessages([...messages, newMessage])

Comments

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.