简体   繁体   English

如何在 useEffect 内的侦听器内访问 state?

[英]How to access state inside a listener inside a useEffect?

I understand that without dependencies you cannot access state inside useEffect .我知道如果没有依赖项,您将无法在 useEffect 中访问useEffect An example as such:一个这样的例子:

 const [state, setState] = React.useState('')
 const ws = new WebSocket(`ws://localhost:5000`)

 React.useEffect(() => {
    ws.onopen = () => {
      console.log(state)
},[])

In this case state comes back as empty even though it has changed in other parts of the code.在这种情况下, state返回为空,即使它在代码的其他部分已更改。 To solve this in principle I should add state as dependency to the useEffect hook.为了原则上解决这个问题,我应该添加state作为 useEffect 挂钩的依赖项。 However, this will trigger the listener again and I do not want to have 2 active listeners on my websocket or being forced to close and reopen it again as such:但是,这将再次触发监听器,我不想在我的websocket上有 2 个活动监听器,或者被迫关闭并再次重新打开它:

 React.useEffect(() => {
    ws.onopen = () => {
      console.log(state)
},[state])

What is good practice when it comes to accessing state inside a listener that sits inside useEffect hook?在位于useEffect挂钩内的侦听器中访问state时,有什么好的做法?

Try this approach:试试这个方法:

  const [state, setState] = React.useState('');
  const stateRef = React.useRef(state);

  React.useEffect(() => {
    stateRef.current = state;
  }, [state])

  const ws = React.useMemo(() => {
    const newWS = new WebSocket(`ws://localhost:5000`);
    newWS.onopen = () => {
      console.log(stateRef.current);
    }
    return newWS;
  }, []);

This way you create the ws only once, and it will use the state reference which will be up to date because of the useEffect .这样,您只需创建一次ws ,它将使用 state 参考,由于useEffect ,该参考将是最新的。

If you don't need to re-render the component when the state updates you can remove const [state, setState] = React.useState('');如果您在 state 更新时不需要重新渲染组件,您可以删除const [state, setState] = React.useState(''); and the useEffect and just update the stateRef like this when you need - stateRef.current = newValue;useEffect并在需要时像这样更新stateRef - stateRef.current = newValue;

Best Practice get data in listeners.[UPDATED]!最佳实践在侦听器中获取数据。[更新]!

const [socketData , setSocketData] = useState(null);
useEffect(() => {
  websocet.open( (data) => {
       setSocketData(data);
    })
},[])
//second useEffect to check socketData
  useEffect(() => {
   if(socketData){
     // access to data which come from websock et
   }
},[socketData])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM