使用 useState 钩子每秒更新一次对象

Update object every second with useState hook

我每 2 秒生成一个随机数,并检查我的状态对象数据是否有这个数字作为键。如果是这样,则增加该值,否则将其作为默认值为 1 的新字段插入到对象中。但是,每当随机数函数运行时,我的状态对象数据为空,因此 data.hasOwnProperty 始终为 false .为什么会这样?

  const [data, setData] = useState({});
  useEffect(() => {
    //INTERVAL TO GENERATE RANDOM NUMBER EVERY 2 SECONDS
    const interval = setInterval(() => {
      generateRandomStock();
    }, 2000);

    return () => {
      clearInterval(interval);
    };
  }, []);

  //GENERATES A RANDOM NUMBER AND UPDATES THE STATE 
  const generateRandomStock = () => {
    const randNumber = Math.floor(Math.random() * 9 + 1).toString();
    console.log(data)
    if (data.hasOwnProperty(randNumber)) {
      console.log("has");
      setData((prevState) => ({
        ...prevState,
        [randNumber]: prevState[randNumber] + 1,
      }));
    } else {
      console.log("does not have");
      setData((prevState) => ({
        ...prevState,
        [randNumber]: 1,
      }));
    }
  };

generateRandomStock 函数创建一个具有初始 data 值的闭包。这始终是一个空对象 {}。您可以访问接收到回调函数的 data 到 `setData 方法,它提供更新的值。

像下面这样尝试

  const generateRandomStock = () => {
    const randNumber = Math.floor(Math.random() * 9 + 1).toString();
    setData((prevData) => {
      console.log(prevData);
      if (prevData.hasOwnProperty(randNumber)) {
        return {
          ...prevData,
          [randNumber]: prevData[randNumber] + 1
        };
      } else {
        console.log("does not have");

        return {
          ...prevData,
          [randNumber]: 1
        };
      }
    });
  };

您需要在 useEffect 挂钩中添加 generateRandomStock 函数作为依赖项。 由于此函数使用 data 值,因此在更新 data 值时更新其内容。

const [data, setData] = useState({});

  //GENERATES A RANDOM NUMBER AND UPDATES THE STATE
  const generateRandomStock = () => {
    const randNumber = Math.floor(Math.random() * 9 + 1).toString();
    console.log(data);
    if (data.hasOwnProperty(randNumber)) {
      console.log("has");
      setData((prevState) => ({
        ...prevState,
        [randNumber]: prevState[randNumber] + 1
      }));
    } else {
      console.log("does not have");
      setData((prevState) => ({
        ...prevState,
        [randNumber]: 1
      }));
    }
  };

  useEffect(() => {
    //INTERVAL TO GENERATE RANDOM NUMBER EVERY 2 SECONDS
    const interval = setInterval(() => {
      generateRandomStock();
    }, 2000);

    return () => {
      clearInterval(interval);
    };
  }, [generateRandomStock]);