来自套接字的数据不会使用useEffect更新状态

时间:2020-07-04 23:08:23

标签: reactjs react-native

参见演示here

我正在连接到套接字(由setTimeouts建模!)并获得一个数组。在安装时,我得到一个初始阵列。然后,我继续监听该阵列的更新。更新仅作为更改而不是整个数组发送。

我需要访问当前状态,但是它是空的。即使在渲染中看起来不错。

我认为这可能是由于numbers在调用addLater()时为空而导致的范围限定或关闭错误,但是我不确定解决方案是什么。

import React, { useEffect, useState } from "react";
import "./styles.css";

export default function App() {
  const [numbers, setNumbers] = useState([]);

  useEffect(() => {
    // initial connection to socket
    setNumbers(["first", "second", "third"]);

    // incoming messages from socket
    addLater();
    addMuchLater();
  }, []);

  const addLater = () => {
    window.setTimeout(() => {
      console.log("Why is the state empty? ", numbers);
      const changedNumbers = [...numbers];
      changedNumbers.splice(1, 1, "fourth");
      setNumbers(changedNumbers);
    }, 5000);
  };

  const addMuchLater = () => {
    window.setTimeout(() => {
      const changedNumbers = [...numbers];
      changedNumbers.splice(2, 1, "fifth");
      setNumbers(changedNumbers);
    }, 10000);
  };

  return (
    <div className="App">
      {numbers.map((r, i) => (
        <p>
          {i}: {r}
        </p>
      ))}
    </div>
  );
}

2 个答案:

答案 0 :(得分:1)

当下一个值取决于上一个值时,最好将代码编写为functional update,这样代码将始终作用于最新值。遇到问题时,当前代码将关闭numbers原始值,这不是您想要的:

const addLater = () => {
  window.setTimeout(() => {
    setNumbers(prevNumbers => {
      const changedNumbers = [...prevNumbers];
      changedNumbers.splice(1, 1, "fourth");
      return changedNumbers;
    });
  }, 5000);
};

const addMuchLater = () => {
  window.setTimeout(() => {
    setNumbers(prevNumbers => {
      const changedNumbers = [...prevNumbers];
      changedNumbers.splice(2, 1, "fifth");
      return changedNumbers;
    });
  }, 10000);
};

答案 1 :(得分:0)

setState是异步的,因此稍后在函数中发生的状态调用将获得呈现组件时的状态,而不是设置新状态后的状态。您可以将回调函数用作第二个参数:

useEffect(() => {
// initial connection to socket
setNumbers(["first", "second", "third"],
()=>{
// incoming messages from socket
addLater();
addMuchLater();
}), []);

请参阅: https://upmostly.com/tutorials/how-to-use-the-setstate-callback-in-react