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.
useEffect(() => {...}, [messages]); to App.js to check if new messages are saved - and they are.console.log(messages) to the addMsg() 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 ...
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 ...
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.
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.