试图创建一个受控的切换器按钮

时间:2017-09-12 07:11:06

标签: reactjs eslint

我已经在线获取此代码(它在Google搜索结果中排名靠前): https://codepen.io/BuiltByEdgar/pen/jWOVYQ

但我已经厌倦了它的代码。

我试图拥有这些按钮的二重奏,其中默认状态为开启且不允许两者都关闭。我选择的用户界面行为只是在关闭其他兄弟姐妹的情况下重新启用另一个:

@immutable

和渲染:

onONEClick() {
    let {
        TWO,
        ONE,
    } = this.state;

    if (TWO) {
        ONE = !ONE;
    } else if (ONE) {
        TWO = !TWO;
        ONE = !TWO;
    } else {
        ONE = !ONE;
    }

    this.setState({
        ONE,
        TWO,
    });
    this.props.callBack({
        ONE,
        TWO,
    });
}
onTWOClick() {
    let {
        TWO,
        ONE,
    } = this.state;

    if (ONE) {
        TWO = !TWO;
    } else if (TWO) {
        TWO = !TWO;
        ONE = !ONE;
    } else {
        TWO = !TWO;
    }

    this.setState({
        ONE,
        TWO,
    });
    this.props.callBack({
        ONE,
        TWO,
    });
}

足够简单吧?

问题是反应讨厌我的切换器输入类型"复选框" : error message

正如你所看到的那样,我已尽力避免这种情况发生,但我认为只是在卡片中没有输入类型并改变它的检查状态而不是通过一个人。

所以我想我也许可以通过重建带有div的复选框来解决问题。 (标签标签也违反了ESLint)

JLAITIO的回答:

以及我添加的内容(带有props声明和构造函数的文件的顶部):

     <div>
        <div className="switch-container">
            <label>
                <input
                    onChange={this.onONEClick}
                    type="checkbox"
                    className="switch"
                    value={this.state.ONE}
                    checked={this.state.ONE}
                />
                <div>
                    <span><g className="icon icon-toolbar grid-view" /></span>
                    <span><g className="icon icon-toolbar ticket-view" /></span>
                    <div />
                </div>
            </label>
        </div>
        ONE
    </div>
    <div>
        <div className="switch-container">
            <label>
                <input
                    onChange={this.onTWOClick}
                    type="checkbox"
                    className="switch"
                    value={this.state.TWO}
                    checked={this.state.TWO}
                />
                <div>
                    <span><g className="icon icon-toolbar grid-view" /></span>
                    <span><g className="icon icon-toolbar ticket-view" /></span>
                    <div />
                </div>
            </label>
        </div>
        TWO
    </div>

2 个答案:

答案 0 :(得分:2)

如果在任何点没有设置value属性,或者设置为undefined的值,则会出现此错误,然后它就是现有的反应状态值。

我最好的猜测是你的构造函数没有初始化ONETWO,因此值为undefined。然后当你实际有一个值时,组件从一个不受控制的(=“独立于React的组件状态”)转移到受控(=“组件状态直接绑定到React状态”)。

答案 1 :(得分:1)

作为@ jlaitio回答的补充,

您不必为复选框输入设置值。您可以使用组件的已检查道具。此外,对于更改的函数的一个小改进可能更有助于更容易地跟踪值。

  constructor(props) {
    super(props);
    this.state = {
      ONE: true,
      TWO: true
    };
  }
  onONEChange = (event) => {
    this.setState((prevState) => {
      ONE: event.target.checked,
      TWO: (event.target.checked === false ? true : prevState.TWO) // change state of TWO if ONE is false else just leave it as is
    }, () => {
        this.props.callBack({ ONE: this.state.ONE, TWO: this.state.TWO });
    });
  }
  onTWOChange = (event) => {
    this.setState((prevState) => {
      ONE: (event.target.checked === false ? true : prevState.ONE), // change state of ONE if TWO is false else just leave it as is
      TWO: event.target.checked
    }, () => {
        this.props.callBack({ ONE: this.state.ONE, TWO: this.state.TWO });
    });
  }