【发布时间】:2021-07-25 05:14:10
【问题描述】:
我查看了一些类似的线程,但没有一个解决此问题。
当我单击一个频道时,它会将其设置为通过setActiveChannel 和activeChannel 通过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