I'm trying to code a chatbot interface using React hooks and Wit.ai.
I have tried setting the messages imperatively (setMessages([...messages, currentValue]) but that doesn't work either. Here's the code:
const [currentValue, setCurrentValue] = useState('');
const [messages, setMessages] = useState([]);
const handleChange = (event) => {
setCurrentValue(event.target.value); // handling input change
}
const sendMessage = (event) => {
event.preventDefault();
if (currentValue.trim() !== '' || currentValue.trim().length > 1) {
witClient.message(currentValue).then(data => {
setMessages(() => [...messages, {text: currentValue, sender: 'user'}]); // here i set the user message
if (data.entities) {
setMessages(() => [...messages, {text: 'message from bot', sender: 'bot'}]); // this line seems to overwrite the user message with the bot message
setCurrentValue('');
}
});
}
document.querySelector('input').focus();
}
When I handle the bots response it overwrites the users message.
When you access messages
after the if statement
you're actually overwritting the first changes, cause [...messages, {text: currentValue, sender: 'user'}]
will only be reflected in the next render
. Set your changes all at once to prevent this
const sendMessage = (event) => {
event.preventDefault();
if (currentValue.trim() !== '' || currentValue.trim().length > 1) {
witClient.message(currentValue).then(data => {
let newMessages = [...messages, {text: currentValue, sender: 'user'}]
if (data.entities) {
newMessages = newMessages.concat({text: 'message from bot', sender: 'bot'})
setCurrentValue('');
}
setMessages(messages)
});
}
document.querySelector('input').focus();
}