【问题标题】:React useState & useEffect confusionReact useState 和 useEffect 混淆
【发布时间】:2022-01-12 00:29:29
【问题描述】:

我对使用 React 功能组件实现某些东西有些困惑。我知道 useState 是异步的,并且在改变状态后读取时不会反映该值。但是我不知道如何实现我正在尝试做的事情。基本上在我的 React 组件中,当它挂载时,我通过 websocket 连接向服务器询问一些后端信息并将其设置为状态。执行此操作后,我立即执行基于开关的方法,但是我无法访问该方法中的状态,因为我刚刚改变了状态并且因为它是异步的,所以更改不会直接反映。这是我的代码:

    useEffect(() => {
      socket.emit("crash:info", (resp) => {
        const { status, gameId, gameHistory, mockVariable } = resp;
        setGameId(gameId);
        setGameHistory(gameHistory);
        setStatus(status);

        switch (status) {
          case 2:
            handleGameEnd({ variable: mockVariable });
            break;
        }
      });
    }, []);
  const handleGameEnd = function (data) {
    //other code with this variable...
    const { variable } = data;

    //here is the issue; gameId is undefined because it is not set by the state yet because setState is async
    if (gameHistory.filter((game) => game.gameId === gameId).length > 0) {
      return;
    }
    setGameHistory((gameHistory) => {
      const newGameHistory = [...gameHistory];
      newGameHistory.unshift({ gameId: gameId });
      newGameHistory.pop();
      return newGameHistory;
    });
  };

有人有想法吗?

【问题讨论】:

  • 你能把相关数据(即gameId作为参数传递给这个函数吗?variable从未使用过。我推荐minimal reproducible example
  • @ggorlen 我添加了变量作为示例,因为此处需要其他数据,而本示例不需要这些数据。我添加它是为了清楚地表明这个函数接受变量。但是是的,我可以将 gameId 作为参数传递给这个函数。
  • 我会考虑将你的前两行从 useEffect 中取出并放入它自己的钩子中。从那里您可以保留 useEffect 来设置所有状态变量,并将 resp 变量放在 useEffect 的依赖数组中。
  • @Steve 我不太明白你的意思,你能给出一个代码方面的例子吗?
  • "但是是的,我可以将gameId 作为参数传递给这个函数。" ——那么问题就解决了吗?

标签: javascript reactjs react-hooks use-effect use-state


【解决方案1】:

反应就像我在跟你开玩笑一样,为什么你要设置两次 gameHistory 状态,你可以做你所有的逻辑,然后像这样在最后调用所有 setStates

    useEffect(() => {
      socket.emit("crash:info", (resp) => {
        const { status, gameId, gameHistory, mockVariable } = resp;

        switch (status) {
          case 2:
            handleGameEnd({ variable: mockVariable, gameId, gameHistory });
            break;
        }


       setStatus(status);
       setGameId(gameId);
       // you already set gameHistory no need for that
       //setGameHistory(gameHistory); 
      });
    }, []);

  const handleGameEnd = function (data) {
    //other code with this variable...
    const { variable, gameId, gameHistory } = data;

    //now you have both gameId and gameHistory 
    if (gameHistory.filter((game) => game.gameId === gameId).length > 0) {
      return;
    }
    setGameHistory((gameHistory) => {
      const newGameHistory = [...gameHistory];
      newGameHistory.unshift({ gameId: gameId });
      newGameHistory.pop();
      return newGameHistory;
    });
    // you can either setState here 
      setGameId(gameId);
      setGameHistory(gameHistory);
    // or back to useEffect block
  };

【讨论】:

    猜你喜欢
    • 2020-02-17
    • 2020-10-11
    • 2021-06-23
    • 2020-03-23
    • 2022-06-18
    • 2020-11-29
    • 1970-01-01
    • 2020-02-14
    • 1970-01-01
    相关资源
    最近更新 更多