【问题标题】:React context state resets because of Socket.io?由于 Socket.io,React 上下文状态重置?
【发布时间】:2021-07-25 05:14:10
【问题描述】:

我查看了一些类似的线程,但没有一个解决此问题。

当我单击一个频道时,它会将其设置为通过setActiveChannelactiveChannel 通过ChannelContext 传递。一切正常,通道对象设置为此状态。但是,当我通过输入 => 套接字服务器 => 客户端发送消息并执行带有 [socket] 的 useEffect msgListener 无法读取 activeChannel 对象时,它似乎回到了 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();

【问题讨论】:

    标签: javascript node.js reactjs sockets socket.io


    【解决方案1】:

    好的,知道了。我又写了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]);
    

    【讨论】:

      猜你喜欢
      • 2018-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-28
      • 1970-01-01
      • 2022-09-29
      • 2016-02-29
      • 1970-01-01
      相关资源
      最近更新 更多