在哪里使用 React 中的 Hooks 定义需要来自全局状态的数据的套接字事件侦听器
Posted
技术标签:
【中文标题】在哪里使用 React 中的 Hooks 定义需要来自全局状态的数据的套接字事件侦听器【英文标题】:Where to define socket event listeners that require data from global state using Hooks in React 【发布时间】:2020-08-10 15:46:16 【问题描述】:我一直在学习钩子,但一个概念仍然让我很困惑。
使用 useEffect 时,内部声明的任何变量在下一次重新渲染后都会变旧。要访问 useEffect 中的更改值,最常见的答案和一个Dan Abramov uses himself 是改用 useRef 挂钩。
但是,假设您想使用 Redux 之类的东西将一条信息存储在全局状态中,但您还希望该信息在 useEffect 内部的回调函数中可用。在我的特定情况下,当我的组件挂载时,我需要将事件侦听器添加到连接到服务器的 Web 套接字,以发出 WebRTC 连接的信号。 Web 套接字侦听器回调函数所需的值将在整个应用程序的使用过程中更新。
如何组织一个全局可访问的状态,但也可以像访问 useRef 生成的 ref 一样被引用?
这是我的意思的一个例子
//App.js
import React, useEffect from "react"
import useSelector from "react-redux"
import socketIOClient from "socket.io-client";
const App = () =>
const users = useSelector(state => state.users)
let socket
//when the component mounts, we establish a websocket connection and define the listeners
useEffect(() =>
socket = socketIOClient(URL)
//in my app in particular, when the user decides to broadcast video, they must make new RTCPeerConnections
//to every user that has logged in to the application as well
socket.on("requestApproved", () =>
//at this point, the users array is outdated
users.forEach(callbackToCreateRTCPeerConnection)
)
, [])
当客户端从服务器收到他们可以开始广播的响应时,客户端需要准确反映哪些用户在使用应用程序的过程中登录。显然,users
的值此时已过时,因为即使来自 useSelector 的值在 useEffect 内部也没有更新,尽管它在外部。所以我可以在这里使用 useRef 来实现我想要的,但这不是我使用 users 数组的唯一地方,我不想一遍又一遍地传递一个 ref 作为道具。
我已经阅读了有关使用 useContext 的信息,但是,如果我理解正确,当上下文值发生变化并且整个应用程序正在使用上下文时,就会为整个应用程序触发重新渲染。
有什么想法、建议、解释吗?除了 useEffect 之外,也许还有更好的地方可以将事件侦听器添加到套接字?
提前致谢。
【问题讨论】:
【参考方案1】:关于监听器的想法是它们应该在闭包值更新时被销毁并重新创建,并在卸载时清理。您可以将用户依赖项添加到 useEffect
并清理侦听器
const App = () =>
const users = useSelector(state => state.users)
let socket
//when the component mounts, we establish a websocket connection and define the listeners
useEffect(() =>
socket = socketIOClient(URL)
//in my app in particular, when the user decides to broadcast video, they must make new RTCPeerConnections
//to every user that has logged in to the application as well
const listener = () =>
//at this point, the users array is outdated
users.forEach(callbackToCreateRTCPeerConnection)
socket.on("requestApproved", listener);
return () =>
socket.off("requestApproved", listener);
, [users])
【讨论】:
以上是关于在哪里使用 React 中的 Hooks 定义需要来自全局状态的数据的套接字事件侦听器的主要内容,如果未能解决你的问题,请参考以下文章
react自定义hooks-自动改变页面的title,Http请求hooks等..(持续更新)
mobx中的inject,observer迁移至react Hooks写法
更改数组中的一个状态会导致在 React Hooks 中重新渲染整个循环生成的自定义组件