无限循环或使用中缺少依赖项

时间:2020-10-24 20:11:36

标签: reactjs react-hooks

每当有新状态时,我都想在以前的状态上应用功能。 用户案例:用户与服务器建立连接。我创建一个WebSocket对象,并将其放入webSocketInstance中。当用户输入用户名时,我将该名称添加到Redux中,这将导致重新呈现组件,这是可以的。现在,由于他具有用户名,因此我希望他使用新的URL重新连接(也是重新连接逻辑的这一部分)。所以我要他关闭以前的连接并打开一个新的连接。

export default function GameKeeper() {
  // Redux states here
  const { adminWsUrl, clientWsUrl, clientCode, playerName } = useSelector(
    (state: RootState) => state.hosting
  );
  const [webSocketInstance, setWebSocketInstance] = useState<WebSocket>();
  
  useEffect(() => {
    if (webSocketInstance) {
      webSocketInstance.close();
    }
    if (adminWsUrl) {
      setWebSocketInstance(new WebSocket(adminWsUrl));
    } else if (clientWsUrl && playerName) {
      setWebSocketInstance(new WebSocket(`${clientWsUrl}${playerName}/`));
    } else if (clientWsUrl && !playerName) {
      setWebSocketInstance(new WebSocket(clientWsUrl));
    }
  }, [adminWsUrl, clientWsUrl, playerName]);
  
  
 return (
  ...
 );
 
}

当前代码警告我webSocketInstance不在useEffect依赖项中。如果添加它,则会出现无限循环。

1 个答案:

答案 0 :(得分:1)

这是我如何设置useReducer来处理此问题的基本模板。我真的想不出一种仅通过useState来完成此操作的好方法,而又没有利用某些可变状态(即useRef)来保存Web套接字。当然,这样做的缺点是您已经完全摆脱了React的状态系统,无法再监视套接字进行更新了。

function wsReducer(wsInstance, action) {
  if (action.type === "reset") {
    wsInstance && wsInstance.close();
    return new WebSocket(action.payload);
  }
}

export default function App() {
  const { adminWsUrl, clientWsUrl, clientCode, playerName } = useSelector(
    (state: RootState) => state.hosting
  );
  const [wsInstance, dispatch] = useReducer(wsReducer, null);

  useEffect(() => {
    const url = (() => {
      if (adminWsUrl) return adminWsUrl;
      if (clientWsUrl && playerName) return `${clientWsUrl}${playerName}/`;
      if (clientWsUrl && !playerName) return clientWsUrl;
      return false;
    })();

    if (url) {
      dispatch({ type: "reset", payload: url });
    }
  }, [adminWsUrl, clientWsUrl, playerName]);

  return (
    ...
  );
}

此外,还有一些recommended reading-尤其是有关在这种情况下解耦更新/操作并使用useReducer的内容。我建议尝试通读一下整个内容,当我开始进行功能性React时,这对我来说真的很有用。