useDocumentation
Setting the scene
Between talks at React Europe Conference I was working on a chat interface in React Native, backed by Amazon Lex. I encountered a fun bug, where the message typed by the user was rendering very briefly, only to be mysteriously whisked away again when the response came back from Lex and the message was supposedly appended to the array of sent and received messages.
The broken code
const appendMessage = ({ message, from }) => {
setMessages([...messages, { message, from }]);
if (from === "me") {
sendToLex(message);
}
};
For a little context - this function takes an object which contains a message and the sender (either 'me', or 'bot'). If from
is set to me
then the message
is sent to Lex as well as being set in the component's state.
The fix
Okay, so first thing is to actually read the documentation. That doesn't mean opening it and scrolling for a bit, but actually reading it. If I'd done this, i'd have spotted:
Functional updates
If the new state is computed using the previous state, you can pass a function to setState. The function will receive the previous value, and return an updated value. Hereβs an example of a counter component that uses both forms ofsetState
:
Ah. So by simply changing
setMessages([...messages, { message, from }]);
to
setMessages(oldMessages => [...oldMessages, { message, from }]);
This now works, producing the following behaviour
That's all there is to it. This is analagous to the 'old' way of setting state using:
this.setState(oldState => ({ value: oldState.value }));
...which I should've really thought about when writing the function in the first place!
Top comments (0)