繁体   English   中英

React + useState + Array + Mutation = 错误

[英]React + useState + Array + Mutation = error

在函数 writeMessage 上,我需要用传入的新消息填充名为 chat 的数组。 为此,我尝试了三种选择,但都没有运气。 如果没有突变,它们只采用initalState 并丢弃其他更改。 并且通过突变,它不会重新渲染自身。 任何帮助将不胜感激。

const writeMessage = (msg) => { //newChat = chat.concat(msg); //newChat = [...chat, msg]; 这两个采用初始状态,但不适用于修改后的状态 //setChat(newChat); 聊天推送(味精); // 这会发生变化 :( 并且有效,但不会重新渲染自身 }

我的代码:

 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>

我希望将新消息添加到数组中而不会发生突变并保持之前发送的消息。

使用 useState 时,您可以使用prevState和扩展运算符来创建这样的新数组。

const writeMessage = (msg) => {
  setChat((prevState) => [...prevState, msg]);
}

使用此方法,您不会改变状态并且组件会再次呈现。

我认为您正在尝试直接改变聊天。 使用setChat代替:

编辑:您应该将 userReducer 用于非原始值。 https://reactjs.org/docs/hooks-reference.html#usereducer

  const writeMessage = (msg) => {
   setChat([...chat, newChat]); // This should re-render
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM