在函数writeMessage上,我需要使用传入的新消息填充名为chat的数组。为此,我尝试了三种没有运气的选择。没有突变,它们仅采用initalState并丢弃其他更改。随着突变,它不会重新呈现自己。任何帮助将不胜感激。
const writeMessage =(msg)=> { // newChat = chat.concat(msg); // newChat = [... chat,msg];这两个具有初始状态,但不适用于修改状态 // setChat(newChat); chat.push(msg); //此方法会更改:(并起作用,但不会重新渲染自身 }
我的代码:
import React, {useEffect, useState} from 'react';
import openSocket from 'socket.io-client';
import './App.css';
const App = () => {
var socket = openSocket('http://localhost:3001/')
var newChat= [];
const [message, setMessage] = useState("");
const [chat, setChat] = useState([{msg:"Hola"},{msg:"Todo Bien?"}])
useEffect(() => {
socket.on('new message', function(msg){
writeMessage(msg)
});
},[])
const writeMessage = (msg) => {
//newChat = chat.concat(msg);
//newChat = [...chat, msg]; this two takes inital State, but doesn not work with modified state
//setChat(newChat);
chat.push(msg); //this mutates :( and works, but does not re-render itself
}
const sendMessage = () => {
if(message === ""){
alert("Write something please");
}else{
socket.emit('send message', message);
setMessage("");
}
console.log(chat);
}
return (
<div>
<ul id="messages">{chat.map((msg, index) => <li key={index}>{msg.msg}</li>)}</ul>
<form>
<input id="m" autoComplete="off" value={message} onChange={(e) => setMessage(e.target.value)}/>
<button type="button" onClick={sendMessage}>Send</button>
</form>
</div>)
}
export default App
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
我希望在不进行任何更改的情况下将新消息添加到阵列中,并保持以前发送的消息。
答案 0 :(得分:1)
使用useState时,可以使用prevState
和散布运算符来创建一个像这样的新数组。
const writeMessage = (msg) => {
setChat((prevState) => [...prevState, msg]);
}
使用此方法,您无需更改状态,组件即可再次呈现。
答案 1 :(得分:0)
我认为您正在尝试直接更改聊天内容。请改用setChat
:
编辑: 您应该将userReducer设置为非原始值。 https://reactjs.org/docs/hooks-reference.html#usereducer
const writeMessage = (msg) => {
setChat([...chat, newChat]); // This should re-render
}