我刚开始研究反应,我有问题 假设我从服务器接收数据,我需要使用一些过滤器将其添加到我的前面。 数据是数组名|年龄 我想以 1 秒的间隔将它添加到前面,所以我需要每 1 秒更新一次我的状态,我尝试了一些变体,但没有任何效果。 那么有人可以帮助我了解如何每 1 秒使用 setState 更新状态吗? 这是我的代码
function App() {
const people = [
{name: 'David', age: 24},
{name: 'James', age: 16},
{name: 'Angela', age: 29},
{name: 'Gina', age: 28},
{name: 'Mike', age: 15},
{name: 'Laura', age: 30},
{name: 'Paul', age: 25}
]
const [btnDisabled, setBtnDisabled] = useState(false)
const [canDrink, setCanDrink] = useState([])
const interval = function () {
let i = 0;
console.log(i)
const interval = setInterval(() => {
console.log(i)
if (people[i]) {
setBtnDisabled(true)
if(people[i].age >= 18) {
const arr = [...canDrink, people[i]]
i++
// @ts-ignore
setCanDrink(arr)
}
} else {
clearInterval(interval)
setBtnDisabled(false)
}
}, 500)
}
return (
<div className="App">
<button
disabled={btnDisabled}
onClick={() => {
interval()
}}>Interval
</button>
<ul>{canDrink.map( elem =>
// @ts-ignore
<li key={elem.name}>{ elem.name }</li>
)}
</ul>
</div>
);
}
答案 0 :(得分:0)
您需要解决两件事。首先,将 i++
移出 if 块。只有当条件满足时,您才会增加计数器。当它看到有人未成年时,它永远不会增加计数器并无限循环。移动它后,您会注意到您的 canDrink
状态正在发生变化,但很奇怪。那是因为您的区间函数只知道 canDrink
数组的第一个版本(请参阅 closures)。您可以使用 setCanDrink(previousState => [...previousState, people[i]])
更新您的状态
答案 1 :(得分:0)
您正在寻找的是React.useEffect
。您无法在功能组件内有效地执行 setTimout
。
首先你必须存储一个新的状态变量来记住索引。
const [counter, setCounter] = React.useState(-1);
然后您可以在 React.useEffect
中实现逻辑,当您的 counter
变量更新时,该逻辑将运行。
React.useEffect(() => {
// This code will run whenever your `counter` variable updates
// Checking if counter is a valid index
if (counter >= 0 && people[counter]) {
// If age of person at `counter` index is < 18, don't do anything, just update counter
if (people[counter].age < 18) setCounter(counter + 1);
// If it is a valid user, setTimeout to update canDrink with this user which will update UI after 1 sec
else {
setTimeout(() => {
setCanDrink((canDrink) => [...canDrink, people[counter]]);
setCounter(counter + 1);
}, 1000);
}
}
}, [counter]);
我为您制作了一个代码沙箱,其中包含一个工作示例。看看吧。
https://codesandbox.io/s/naughty-ardinghelli-sks6z?file=/src/App.js