由于 Socket.io,反应上下文状态重置?

React context state resets because of Socket.io?

我查看了一些类似的线程,但其中 none 对此有修复。

当我点击一个频道时,它会将其设置为通过 setActiveChannel,而 activeChannel 通过 ChannelContext。一切正常,通道对象设置为此状态。但是当我通过 input => socket server => client 发送消息并执行 useEffect with [socket] msgListener cannot read activeChannel object, it seems like it go back to default value of activeChannel 状态为 {}。

另一件有趣的事情是,例如,当我向文件添加新评论并保存它时,activeChannel 状态是应该的,if (msgData.channelId === activeChannel.channelId) 是真实的。但是当我刷新整个应用程序并开始“新鲜”首先打开频道然后输入消息时,msgListener 无法获得 activeChannel.

  import { ChannelContext } from "../../../context/channel";
  import { socket } from "../../../context/socket";

export default function Chat() {
  const { activeChannel } = useContext(ChannelContext);
  const [messages, setMessages] = useState([]);
  const [newMessage, setNewMessage] = useState(null);
  const classes = useStyles();

  useEffect(() => {
    console.log("Active channel changed");
    console.log(activeChannel.channelId);
    setCurrentState(activeChannel);
    setMessages(activeChannel.messagesByDate);
  }, [activeChannel]);

  const msgListener = (msgData) => {
    console.log("socket message before if: ");
    console.log(msgData.message);
    console.log("activechannel:");
    console.log(activeChannel); // returns {}
    console.log("activechannel id:"); 
    console.log(activeChannel.channelId); //returns undefined

    if (msgData.channelId === activeChannel.channelId) { // therefore not true
      setNewMessage(msgData);
    }
  };
  useEffect(() => {
    if (socket) {
      socket.on("message", msgListener);
      return () => socket.off("message", msgListener);
    }
  }, [socket]); 

...
}

这里是设置频道的代码:

 const { activeChannel, setActiveChannel } = useContext(ChannelContext);

  const getActiveChannel = async (channelId) => {

    try {
      const { data } = await axios.get(`/api/channel/${channelId}`, config);

      if (data) {
        setActiveChannel(data.channel);
      }
    } catch (error) {
      return console.log(error.message);
    }
  };

此处父组件具有 Socket 上下文

const [activeChannel, setActiveChannel] = useState({});
    return (
    <div>
      <ChannelContext.Provider value={{ activeChannel, setActiveChannel }}>

          <SocketContext.Provider value={socket}>
            <Dashboard channelItems={channelItems} getChannels={getChannels} />
          </SocketContext.Provider>
      </ChannelContext.Provider>
      {error && <span>{error}</span>}
    </div>
  );

套接字上下文:

import { createContext } from "react";
import { io } from "socket.io-client";

export const socket = io();

export const SocketContext = createContext();

好的,知道了。我又写了socket useEffect:

useEffect(() => {
    if (socket) {
      socket.on("message", (msgData) => {
        if (activeChannel.channelId) {
          if (msgData.channelId === activeChannel.channelId) {
            setNewMessage(msgData);
          }
        }
      });
      return () => socket.off("message");
    }
  }, [socket, messages]);