首页 > 解决方案 > 不能在反应中使用 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然后再次启动它附加第二个项目然后停止并重复

标签: javascriptarraysreactjsecmascript-6setinterval

解决方案


更改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>;
};

推荐阅读