尝试使用 Interval 更改 React Hooks 中的状态



我在尝试使用setInterval更改反应中的状态时遇到问题。 为什么函数"alert"总是显示"null"消息?

import React, { useEffect, useState } from 'react';
const Playlist = (props) => {
const [test, setTest] = useState("");
useEffect(() => {
setInterval(load, 3000)
}, []);
const load = async () => {
alert(test)
setTest("TEST");
}
return (
<div>
{test}
</div>
)
}
export default Playlist

问题 :

是传递到setInterval闭包中的回调,它在第一次渲染中访问test变量。

溶液:

您可以在状态发生任何变化时立即clearIntervalsetInterval

const { useState , useEffect , useCallback } = React;
const App = () => {
const [test, setTest] = useState("");
useEffect(() => {
const intrvl = setInterval(load, 3000);
return () => clearInterval(intrvl);
}, [test]);

const load = () => {
alert(test)
setTest("TEST");
}
return (
<div>
{test}
</div>
)
}
ReactDOM.render(<App />, document.getElementById('react-root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react-root"></div>

问题是useEffect从第一个渲染中捕获等于空字符串的test。我们永远不会重新应用效果,因此 setInterval 中的闭包始终引用第一次渲染中的测试。

注意:setInterval不会及时描述流程 - 一旦设置了间隔,除了清除它之外,您无法更改任何有关它的内容。

当我们将一个空的依赖项[]数组传递给 useEffect 时,它只在挂载时运行 useEffect,在卸载组件时运行清理。

一种方法是将test添加到依赖项数组中,以便每当测试更新时,都会调用 useEffect。

useEffect(() => {
const intervalId = setInterval(load, 3000);
return () => clearInterval(intervalId);
}, [test]);

但是由于我们在useEffect中使用了test,我们可以删除空的[]依赖项数组,因此每次我们设置状态(组件被重新渲染(时都会调用useEffect,并且将通过访问最新的测试状态来创建新的setInterval,如下所示

useEffect(() => {
const intervalId = setInterval(load, 3000);
return () => clearInterval(intervalId);
});

另一种可能的方法是更新区间闭包中的状态,例如

useEffect(() => {
const id = setInterval(() => {
setTest("TEST");
}, 3000);
return () => clearInterval(id);
});

const App = () => {
const [test, setTest] = useState("");
useEffect(() => {
const intervalId = setInterval(load, 3000);
return () => clearInterval(intervalId);
});
const load = () => {
alert(test)
setTest("TEST");
}
return (
<div>
{test}
</div>
)
}

设置计数的间隔示例,以便您可以看到状态更改

相关内容

  • 没有找到相关文章

最新更新