我得到了一个组件,它应该呈现一个聊天屏幕,消息来自socket.io。
构成部分:
export default function ChatScreen() {
const [name, setName] = useState("");
const [message, setMessage] = useState("");
let socket;
useEffect(() => {
socket = io("http://192.168.1.229:3000")
socket.on("chatMessage", messageObj => {
console.log(`The message sender is ${messageObj.name}`)
setName(messageObj.name)
setMessage(messageObj.message)
})
});
return (
<Text>
{name} : {message}
</Text>
);
}这个
console.log(`The message sender is ${messageObj.name}`)正在工作,但它打印了很多次。之后的状态更新根本不起作用。我在控制台上收到一条消息说:
警告:无法对未挂载的组件执行反应状态更新。这是一个非操作,但它表示您的应用程序中存在内存泄漏。若要修复,请在useEffect清理函数%s%s中取消ChatScreen中的所有订阅和异步任务(at SceneView.js:9)
有人明白吗?
发布于 2020-01-17 20:08:14
警告击中了钉子的头。您将在useEffect()中打开一个套接字,但是您不会从它返回一个清理函数,也不会将一个依赖项数组传递给它。第一个问题意味着,如果组件被卸载,套接字将永远不会关闭。第二个问题意味着,每次组件呈现时,都会打开一个新套接字。所以每次发生chatMessage事件,还有另一个套接字,所以每次chatMessage发生时都有两个套接字重新呈现应用程序,依此类推。
要解决第一个问题,请从关闭套接字的useEffect函数返回一个函数。当组件卸载或钩子因更改的依赖关系而触发时,React将调用此函数。
要解决第二个问题,请为依赖项传递一个空数组,因为您没有使用任何通过效果钩子中的道具传递的内容。空数组将防止每次组件重新呈现时运行效果挂钩。
export default function ChatScreen() {
const [name, setName] = useState("");
const [message, setMessage] = useState("");
useEffect(() => {
const socket = io("http://192.168.1.229:3000");
socket.on("chatMessage", messageObj => {
console.log(`The message sender is ${messageObj.name}`);
setName(messageObj.name);
setMessage(messageObj.message);
});
return () => socket.close();
}, []);
return (
<Text>
{name} : {message}
</Text>
);
}我还建议花一些时间阅读React关于useEffect钩子: →的文档。
https://stackoverflow.com/questions/59794079
复制相似问题