反应本机 setInterval useState

时间:2021-06-02 11:04:08

标签: reactjs react-native react-hooks setinterval use-state

我正在创建间隔计数器,下面的代码工作正常。但是我对这段代码有几个我不明白的问题。

import React, { useState, useEffect } from 'react';
import {View, Text} from 'react-native'

const Interval = () => {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      console.log(`seconds: ${seconds}`)
      setSeconds(seconds => seconds + 1);
    }, 1000);
    return () => clearInterval(interval);
  }, []);

  return (
      <View>
        <Text>
          {seconds} seconds have elapsed since mounting.
        </Text>
      </View>
  );
};

export default IntervalExample;
  1. 如果我更简单地用 setSeconds(seconds => seconds + 1); 代替 setSeconds(seconds + 1);,为什么这不起作用?
  2. 为什么 console.log(`seconds: ${seconds}`) 总是记录为 0

2 个答案:

答案 0 :(得分:1)

使用这个;

useEffect(() => {
    const interval = setInterval(() => {
      setSeconds(seconds + 1);
      console.log(seconds)
    }, 1000);

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

答案 1 :(得分:1)

运行 useEffect 您需要将变量作为第二个参数传递(在您的情况下,它是 seconds)。当此变量发生更改时,useEffect 将再次运行。

来自文档:

<块引用>

如果您传递一个空数组 ([]),则效果中的 props 和 state 将始终具有其初始值。虽然传递 [] 作为第二个参数更接近熟悉的 componentDidMount 和 componentWillUnmount 心智模型,但通常有更好的解决方案来避免过于频繁地重新运行效果。另外,不要忘记 React 会将 useEffect 的运行推迟到浏览器完成绘制之后,所以做额外的工作不是问题。

就是这样,您需要将第二个变量传递给 useEfect:

useEffect(() => {...}, [seconds])

在这种情况下,您可以使用 setSeconds(seconds + 1); 代替传递函数。

完整代码:

useEffect(() => {
 const interval = setInterval(() => {
   console.log(`seconds: ${seconds}`)
   setSeconds(seconds + 1)
  }, 1000)
 return () => clearInterval(interval)
}, [seconds])