不能在反应中使用 setinterval() 附加数组(状态元素)
Posted
技术标签:
【中文标题】不能在反应中使用 setinterval() 附加数组(状态元素)【英文标题】:cant append array(state element) with setinterval() in react 【发布时间】:2020-08-16 16:30:54 【问题描述】: const [timer,setTimer] = useState()
const [number, setNumber] = useState()
const [list, setlist] = useState([])
const numberChange = (number)=>
setNumber(number)
if (!(list.find(item=>item===number)))
setlist([...list,number])
const randomNumber=()=> 1+Math.floor(Math.random()*90)
const randNumberChange=()=>
let randNumber = randomNumber()
if (list.find(item=>item===randNumber))
randNumberChange()
else
numberChange(randNumber)
const startTimer = () =>
setTimer(setInterval(()=>
randNumberChange()
, 5000))
const stopTimer=()=>
clearInterval(timer)
列表总是只呈现一项而不是附加它。
当 randNumberChange
被单独调用时,列表会被附加,但不会被 setInterval
附加。
当startTimer
函数被执行时,以stopTimer
停止,然后再次启动它附加第二个项目然后停止并重复
【问题讨论】:
【参考方案1】:将setlist([...list,number])
更改为setlist((prevState) => [...prevState, number])
。 React 设置状态本质上是异步的。因此,要从状态中获取正确的列表值,您需要从先前状态中获取值。 Doc
建议:可以在useEffect
开始间隔,而不是在状态设置定时器。
同样在numberChange
函数中,您应该从之前的状态中获取list
,然后在其中附加新的数字。这将确保在添加新号码之前更新 list
值。
import React, Component, useState from "react";
import render from "react-dom";
import Hello from "./Hello";
import "./style.css";
const Test = () =>
const [number, setNumber] = useState(null);
const [list, setlist] = useState([]);
const numberChange = number =>
setNumber(number);
if (!list.find(item => item === number))
setlist((prevState) => [...prevState, number]);// instead of directly using list value, get it from previous state
;
const randomNumber = () => 1 + Math.floor(Math.random() * 90);
const randNumberChange = () =>
console.log("here");
let randNumber = randomNumber();
if (list.find(item => item === randNumber)) randNumberChange();
else numberChange(randNumber);
;
const startTimer = () =>
return setInterval(() => randNumberChange(); , 5000);
const stopTimer = (timer) =>
clearInterval(timer)
React.useEffect(() =>
const timer = startTimer();
return ()=> stopTimer(timer);
, []);
console.log(list);
return <div>number</div>;
;
【讨论】:
谢谢你的工作。我直接改变了状态。感谢您的帮助【参考方案2】:你需要使用useEffect
钩子:
useEffect(() =>
// You don't need timer state, we'll clear this later
const interval = setInterval(() =>
randNumberChange()
,5000)
return () => // clear up
clearInterval(interval)
,[])
【讨论】:
以上是关于不能在反应中使用 setinterval() 附加数组(状态元素)的主要内容,如果未能解决你的问题,请参考以下文章
卡在反应倒计时应用程序上,想知道如何正确使用 setInterval