更新的状态值未反映在React的setInterval()内部

时间:2020-11-06 00:29:08

标签: javascript reactjs

我有以下内容:

const [isPaused, setIsPaused] = useState(false);
const myTimer = useRef(null);

const startTimer = () => {
  myTimer.current = setInterval(() => {
    console.log(isPaused); // always says "false"
  }, 1000);
};

此计时器运行时,在代码中的其他地方,我正在更新isPaused的值:

setIsPaused(true);

但是这不会反映在控制台日志中,它始终记录为false。有解决办法吗?

2 个答案:

答案 0 :(得分:1)

您可以这样做,

  const [isPaused, setIsPaused] = useState(false);
  const myTimer = useRef(null);

  const startTimer = () => {
    myTimer.current = setInterval(() => {
      console.log(isPaused); // now updates
    }, 1000);
  };

  useEffect(() => {
    startTimer();
    return () => myTimer.current != null && clearInterval(myTimer.current);
  }, [isPaused]);

  return (
    <div>
      <b>isPaused: {isPaused ? "T" : "F"}</b>
      <button onClick={() => setIsPaused(!isPaused)}>Toggle</button>
    </div>
  );

使用其他功能

使用30secondsofcode中的useInterval

const Timer = props => {
  const [seconds, setSeconds] = React.useState(0);
  useInterval(() => {
    setSeconds(seconds + 1);
  }, 1000);

  return <p>{seconds}</p>;
};

ReactDOM.render(<Timer />, document.getElementById('root'));

或者,使用react-useInterval软件包

function Counter() {
  let [count, setCount] = useState(0);
 
  const increaseCount = amount => {
    setCount(count + amount);
  };
 
  useInterval(increaseCount, 1000, 5);
  return <h1>{count}</h1>;
}

答案 1 :(得分:1)

myTimer.current从未更改,这意味着isPaused始终在函数内部false

每次useEffect更新时,您需要利用myTimer.current来更新isPaused

useEffect(() => {
  function startTimer() {
    myTimer.current = setInterval(() => {
      console.log(isPaused);
    }, 1000);
  };
  
  startTimer();
  return () => clearInterval(myTimer.current); // cleanup
}, [isPaused]);