javascript - 不能在反应中使用 setinterval() 附加数组(状态元素)
问题描述
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
然后再次启动它附加第二个项目然后停止并重复
解决方案
更改setlist([...list,number])}
为setlist((prevState) => [...prevState, number])
。React 设置状态本质上是异步的。因此,要从状态中获取正确的列表值,您需要从先前状态中获取值。文档
建议:不要在 state 中设置 timer,你可以在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>;
};
推荐阅读
- redis - Redis 哨兵故障转移配置问题
- lg - 为 LG B460 手机使用 LG 开源软件
- tesseract - OCR PDF转文本
- javascript - 在网页上构建交互式地图网格的更好方法?当前使用“table”元素
- airflow - 您在哪里查看气流作业的输出
- c++ - QFileDialog getSaveFileName 使程序崩溃
- java - 打印到收据打印机:Java
- orientdb - 使用 OrientDB 扩展时的性能问题
- postgresql - 任务管理器中的许多 PostgreSQL 进程
- javascript - 根据上一页中的选定值显示不同的表单字段 - c# razorview