为啥 this.setState 在我的情况下有效

Posted

技术标签:

【中文标题】为啥 this.setState 在我的情况下有效【英文标题】:Why does this.setState work in my case为什么 this.setState 在我的情况下有效 【发布时间】:2019-01-16 09:31:20 【问题描述】:

我只是想创建一个非常简单的应用程序,我将输入一个数字,计算机将生成带有该数字的框,并一次随机更改一个框的颜色。代码有效,但我不明白它为什么有效,在 randomBlinking 函数中,我只需要 this.setState() 或更奇怪,我可以在 this.setState() 和代码将相同,它将每 1 秒更改一个随机框的颜色。我将我的应用程序缩减为我不理解的部分,有人可以帮我回答这个问题。

import React from 'react';
import CubeRender from '../therapeuticEffect/CubeRender';
import '../therapeuticEffect/style.css';

class TherapeuticEffect extends React.Component 
constructor(props) 
    super(props)
    this.state = 
        cubeArray: [],
        cubeNumber: 0,
        cubeSize: 100,
    
    this.blinking = null;


onNumberChange = (event) => 
    this.setState( [event.target.name]: event.target.value )


onFormSubmit = (event) => 
    event.preventDefault();
    clearInterval(this.blinking);
    this.cubeArrayRender();


cubeArrayRender = () => 
    let  cubeNumber  = this.state;

    let cubes = parseInt(cubeNumber, 10);

    let array = cubes ? Array(cubes).fill() : [];
    let cubeArray = array.length === 0 ? [] : array.map((c) => (this.randomColor()));
    this.setState( cubeArray )
    this.randomBlinking();


randomBlinking = () => 
    this.blinking = setInterval(() => 
        const array = this.state.cubeArray;
            const randIndex = Math.floor(Math.random() * array.length);
            array[randIndex] = this.randomColor();

            //HOW COULD THIS WORK

            this.setState()
    , 500);


randomColor = () => 
    let r = Math.floor(Math.random() * 256);
    let g = Math.floor(Math.random() * 256);
    let b = Math.floor(Math.random() * 256);
    let color = `rgb($r, $g, $b)`
    return color;


render() 
    const  cubeArray, cubeNumber, cubeSize  = this.state
    return (
        <div>
            <form className='menu-bar' onSubmit=this.onFormSubmit>
                <div>
                    <label>cube number </label>
                    <input type='number' name='cubeNumber' value=cubeNumber onChange=this.onNumberChange />
                </div>

            </form>

            <CubeRender
                cubeArray=cubeArray
                cubeSize=cubeSize
            />
        </div>
    )

【问题讨论】:

你正在通过写array[randIndex] = this.randomColor()直接改变你的状态。仅此一项(不推荐)不会重新渲染您的组件。然后,当您编写 this.setState(); 时,组件重新呈现您刚刚变异的状态。 数组不在我的状态 是的。 const array = this.state.cubeArray 数组作为引用存储在 javascript 中。当您说const array = this.state.cubeArray 时,您不是在复制状态数组,而是在创建对它的引用。所以变异 array 也会直接变异状态数组。您需要创建一个副本,这可以通过多种方式完成,例如const array = this.state.cubeArray.slice()const array = [...this.state.cubeArray]。另外,不要将变量称为“数组” 【参考方案1】:

您正在通过写array[randIndex] = this.randomColor() 直接改变您的状态。仅此一项(不推荐)不会重新渲染您的组件。然后,当您编写 this.setState(); 时,组件将使用您刚刚变异的状态重新渲染。

您可以改为创建 cubeArray 数组的副本,并用随机颜色覆盖随机索引,然后用它更新您的状态。

randomBlinking = () => 
  this.blinking = setInterval(() => 
    this.setState(previousState => 
      const cubeArray = [...previousState.cubeArray];
      const randIndex = Math.floor(Math.random() * cubeArray.length);

      cubeArray[randIndex] = this.randomColor();

      return  cubeArray ;
    );
  , 500);
;

【讨论】:

以上是关于为啥 this.setState 在我的情况下有效的主要内容,如果未能解决你的问题,请参考以下文章

如何在我的示例中正确使用 setState()?

react在哪些情况下调用this.setState会导致死循环

如何在 React 中使用 setState() 来空白/清除数组的值

为啥 QSplashscreen 并不总是有效?

如何在我的 setState 函数调用中使用变量?

react setState