如何在 localStorage/use 套接字上存储 socket 在 vanilla ReactJS 的不同组件上,以便在不同的组件中使用 socket.io?

How to store socket on localStorage/use socket on different components on vanilla ReactJS for use in different components socket.io?

提问人:FiFi 提问时间:4/18/2022 最后编辑:FiFi 更新时间:4/18/2022 访问量:685

问:

我想存储套接字,以便我可以在不同的组件中使用它。 当我在登录后第一次在 socket.io 上设置套接字时,我将套接字设置为“套接字”状态下的状态,然后将其存储在 localStorage 上。

useEffect(() => {
        if(!socket) {
            setSocket(io(backendLink));
        };
    }, []) 

useEffect(() => {
        socket?.emit("newUser", localStorage.getItem('authToken'));
        localStorage.setItem('socket', JSON.stringify(socket));
    }, [socket])

然后在不同的组件中,我最初没有设置插座。我使用这样的逻辑:

useEffect(() => {
        if(!socket) socket = localStorage.getItem('socket');
        socket.emit(...)
}, [userID])

上面,如果作为 props 传递的存储在 state 中的套接字为 null,我从 localStorage 恢复套接字并使用它来发出。但是,我得到了 Uncaught TypeError: Converting circular structure to JSON。

据我了解,这是因为我在无法以这种方式转换和存储在 localStorage 上的东西(即套接字)使用了 JSON.stringify。我想使用vanilla reactjs将套接字作为与我使用setSocket(io(backendLink))的文件不同的文件使用。如何使用 vanilla reactJS 跨不同组件使用 socket.io(没有上下文,完全是 vanilla)?

JavaScript ReactJS 套接字 socket.io mern

评论

0赞 Pranavan 4/18/2022
将连接对象作为字符串存储在 localStorage 中不是一个好主意
0赞 FiFi 4/18/2022
我应该如何在不同的文件中使用套接字,然后从我最初使用 vanilla reactjs 设置套接字的地方开始?
0赞 Sonu Bamniya 4/18/2022
您可以将其连接到顶部组件,然后使用上下文共享它。
0赞 Pranavan 4/18/2022
您可以使用 context 或 redux。
0赞 FiFi 4/18/2022
就像如果我存储为状态并作为套接字的道具传递一样,我在页面刷新后的状态上得到 null。它只在第一次起作用,所以我不得不使用 localStorage,在那里我验证套接字是否为 null,从 localStorage 恢复,但它不起作用。

答:

1赞 Cesare Polonara 4/18/2022 #1

你不应该字符串化这样的对象,如果你想在你的应用程序中引用它,你只需要在保存它后将其保存在 React 上下文中。这样,您就可以在整个应用程序中的任何位置访问它。还有其他选择,但这是更安全的选择。

评论

0赞 FiFi 4/18/2022
没有办法在没有上下文的情况下使用 reactjs 来做到这一点吗?
0赞 Cesare Polonara 4/18/2022
是的,您可以将套接字存储在 POJO 中,并在您需要的每个组件中检索它,但该解决方案需要您知道自己在做什么,因为您需要确保在第一次挂载主父项时,套接字已正确创建和存储。如果你不是很有经验,使用 React 状态和上下文是最安全的方法
0赞 FiFi 4/18/2022
当我刷新页面时,我失去了状态。上下文也会解决这个问题吗?似乎所有其他 stackoverflow 帖子都推荐了 localStorage。但是上下文也能解决这个问题吗?
0赞 Cesare Polonara 4/18/2022
当你刷新页面时,你应该创建一个新的socket实例并重新连接它,问题是什么?套接字实例不保持内部状态,那么你要尝试什么来持久化?
1赞 Cesare Polonara 4/18/2022
你只需要在 App 组件上使用 [] dep 在 useEffect 中创建一个套接字实例,它应该是组件树中最高的组件。然后将其保存为 React 状态。然后你可以通过 props 注入它,或者更好地使用 React Context。首次实例化时,无需检查它是否已经存在,因为它在第一个应用程序装载(也称为刷新或首次打开)上不存在。你只需要小心地在其他组件中添加 socket.on() 侦听器,在带有 [socket] deps 的 useEffect 中,并在附加它们之前进行检查。socketif (socket)