useState钩子的set State函数无法与socket.io

时间:2020-06-23 18:03:38

标签: javascript reactjs socket.io frontend react-hooks

我有一个使用react钩子和socketio的组件:

import React, { useState, useEffect } from "react";
import io from "socket.io-client";

const Live = () => {
  const [messages, setMessages] = useState([]);
  const ENDPOINT = "localhost:5000";

  useEffect(() => {
    socket = io(ENDPOINT);
    socket.on("message", (message) => {
      setMessages((messages) => [message, ...messages]);
      //setMessages([message, ...messages]); //It doesn't work
    });
  }, [ENDPOINT]);

  // rest of the code

};

如果我使用setMessages([message, ...messages]),则它不起作用,并且从套接字接收到新消息后,messages数组中的所有先前消息均消失了。这种行为背后的原因是什么?

1 个答案:

答案 0 :(得分:1)

我不建议在这里useState做您正在做的事情。而是考虑使用useReducer

const Live = () => {
  const ENDPOINT = "localhost:5000";

  const [{ messages }, dispatch] = useReducer((state, action) => {
    if (action.type === 'NEW_MESSAGE') {
      state.messages.push(action.message)
      return state
    }
    return state
  }, { messages: [] })

  useEffect(() => {
    socket = io(ENDPOINT);
    socket.on("message", (message) => {
      dispatch({ type: 'NEW_MESSAGE', message })
    });
  }, [ENDPOINT])

  // rest of the code
};

来自useReducer上的React文档

当具有复杂的状态逻辑(涉及多个子值)或下一个状态取决于前一个值时,

useReducer通常比useState更可取。

根据您的情况,下一个messages状态取决于前一个messages状态。