React链式setState打破渲染

时间:2018-05-07 19:30:52

标签: reactjs

我正在尝试创建一个RadioInput组件,但是当我添加一个回调来设置父级内部的状态时,按钮不会保持单击状态。

在RadioInput组件渲染功能的内部我正在创建内部按钮,如下所示:

this.props.buttons.map( (button) => {
    return (
        <div ...>
            <Button clickedDown={this.state.selectedButton === button} clickAction={() => this.radioSelected(button)}.../>
        </div>
    )
}

收音机选择功能然后设置内部收音机输入状态以使点击的按钮成为所选按钮并调用传递给孩子的功能以将选项的值提供给父

radioSelected = (button) => {
    if (this.state.selectedButton !== button) {
        this.setState({selectedButton: button}, () => {
            this.props.clickAction(this.state.selectedButton);
        }
    }
}

RadioInput在父内部声明如下:

render () {
    const buttonList = [
        { color:'green', text:'Green', id: 1 },
        { color:'blue', text:'Blue', id: 2 },
        { color:'purple', text:'Purple', id: 3 }
    ];
    return (
        <RadioInput buttons={buttonList} clickAction={this.radioAction}/>
    )
}

RadioInput的内部radioSelected函数调用的radioAction函数如下所示:

radioAction = (button) => {
    this.setState({
        team: button.color
    });
}

如果我从无线电输入中的this.props.clickAction(this.state.selectedButton);中删除setState,它将正常运行。如果功能正常,我会删除父级setState内的radioAction()。为什么链接的setStates会导致错误,例如阻止clickedDown={this.state.selectedButton === button}不被重新评估?

感谢任何帮助!

2 个答案:

答案 0 :(得分:1)

铊;博士;

x0 = [{a: 'red'}];
x1 = [{a: 'red'}];
console.log(x0[0] === x1[0]); // false 

buttonListconst buttonList = ...)的初始化从render函数移动到构造函数或任何其他不会在每个渲染上更改数组的位置。

解释

在您的父级中,每次调用buttonList时都会重新初始化render。因此,在每次调用父render之后,您都有不同的buttonList,因为每次都是新创建的对象。

现在,您的radioAction函数会调用父setState,调用render并有效地将buttonList的所有项目更改为新的项目数组。绝对this.state.selectedButton不等于它们中的任何一个,因为它是前一个数组中的项目。

答案 1 :(得分:0)

您的clickAction未收到参数:

clickAction={() => this.radioSelected(button)}

它崩溃是因为您使用参数调用它同时clickAction道具没有收到您的参数,所以它只是没有收到this.state.selectedButton

this.props.clickAction(this.state.selectedButton);

所以,它应该是:

clickAction={(button) => this.radioSelected(button)}