'ReactJS state does not return the right value
Problem:
I am building a simple chat app, in App.js I am saving the message history and in Screen.js I handle the input, etc.
The problem I am facing is that when I add a new message to the history it always overwrites the complete history.
What I did:
- I added
useEffect(() => {...}, [messages]);to App.js to check if new messages are saved - and they are. - Then I added a
console.log(messages)to theaddMsg()in App.js AND in Screen.js and discovered that this console.log always returns an empty array.
I have no idea why messages returns data in the useEffect but not inside the addMsg function ...
Code:
App.js
const [messages, addMessage] = useState([]);
# this function is passed down as a prop to add new messages to the history
const addMsg = (data) => {
console.log(' old history', messages);
return addMessage([...messages, data]);
};
...
return (
<div className="App">
<Screen messages={messages} addMsg={addMsg} />
</div>
)
This is how I call the addMsg function from Screen.js:
props.addMsg(data);
Screen.js:
function Screen(props) {
useEffect(() => {
console.log('props.messages', props.messages); // always returns []
}, [props.messages]);
const sendMsg = (msg) => {
let data = {
timestamp: Date.now(),
id: props.id,
msg: msg,
key: props.messages.length+1,
};
props.addMsg(data);
}
return (
<div className="screen">
<div className="messages">
{
props.messages.map(obj => {
return <Row key={obj.key} id={obj.id} timestamp={obj.timestamp} msg={obj.msg} />
})
}
</div>
<Input id={props.id} send={sendMsg} />
</div>
)
}
Basically I just pass an object to addMsg that then get's added to the history (messages) array.
I am relatively new to React and have been stuck on this for hours ...
Clarification
It's a simple chat app. The messages array holds all messages (like a history). When I add a new message the history array get's reset but I do not know why. When I add a message it does get added to the history array (I tested this with an useEffect handler [messages]); but I also added a console.log to the addMessage function that always tells me that my history array is empty ... I have no idea why.
Solution 1:[1]
In your code addMsg returns addMessage which is a useState setter. After that the useEffect handlers get triggered and they already have the updated value.
But an useState setter doesn't return a value, so you'll have to adjust the addMsg function to return a value.
That's why you see the changed value in useEffect and not returned by addMsg
const addMsg = (data) => {
console.log(' old history', messages);
let newMessages = [...messages, data];
addMessage(newMessages);
// After the setter call the 'messages' variable
// is not yet updated, so use the 'newMessages' variable.
return newMessages
};
Now addMsg returns the new array.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
