反应错误:从受控制到不受控制的组件

时间:2019-05-23 15:29:00

标签: javascript reactjs controlled-component

编辑:某些用户将此问题标记为重复。不知道他们在这样做之前是否已阅读过。如果有人这样做,请说明在什么意义上是重复的。

我有一个复选框组件:

class Checkbox extends Component {
    onChange = (e) => {
        if (this.props.input) {
            this.props.input.onChange(e.target.checked);
        } else if (this.props.onChange) {
            this.props.onChange(e.target.checked, this.props.id);
        }
    };

    render() {
        const { input, value, className, label } = this.props;
        let inputValue = (input && input.value) || value;

        return (
            <div className={'Checkbox' + (className ? ' Checkbox--' + className : '')}>
                <input
                    className="Checkbox-input"
                    type="checkbox"
                    onChange={this.onChange}
                    checked={inputValue}
                />
                <span className="Checkbox-helper" />
                <span className="Checkbox-label" htmlFor="">
                    {label}
                </span>
            </div>
        );
    }
}

值更改时,此组件将返回错误。

  

警告:组件正在更改类型的不受控制的输入   复选框进行控制。输入元素不应从   不受控制到受控制(反之亦然)。确定使用   受控制或不受控制的输入元素   组件。

但是如果我替换:

let inputValue = (input && input.value) || value;

使用

let inputValue = value;
if (input) {
    inputValue = input.value;
}

像这样:

class Checkbox extends Component {
    onChange = (e) => {
        if (this.props.input) {
            this.props.input.onChange(e.target.checked);
        } else if (this.props.onChange) {
            this.props.onChange(e.target.checked, this.props.id);
        }
    };

    render() {
        const { input, value, className, label } = this.props;

        let inputValue = value;
        if (input) {
            inputValue = input.value;
        }

        return (
            <div className={'Checkbox' + (className ? ' Checkbox--' + className : '')}>
                <input
                    className="Checkbox-input"
                    type="checkbox"
                    onChange={this.onChange}
                    checked={inputValue}
                />
                <span className="Checkbox-helper" />
                <span className="Checkbox-label" htmlFor="">
                    {label}
                </span>
            </div>
        );
    }
}

它不返回任何错误。为什么?

1 个答案:

答案 0 :(得分:1)

一种可能性(这里没有足够的信息可以肯定地说)是存在input.valuefalse(或虚假),因此您退回到value道具,是undefined,您最终在输入中将checked设置为undefined

这将导致复选框不受控制。

然后,在随后的遍历中,input.valueprops.value都已更改,并且您将checked设置为实数值,这意味着它现在是受控输入,并且react会发出警告。

在最初的情况下,即使value显式为input.valuefalse或为空字符串,您也将获得0道具:

// if input.value === false here you get
// the fallback value which may be undefined
let inputValue = (input && input.value) || value;

在您修改的情况下……

let inputValue = value;
if (input) {
  inputValue = input.value;
}

…您已经避免了这种情况,因为您是根据input本身而不是input.value的存在为前提的。