Ошибка реагирования: от контролируемого к неконтролируемому компоненту - PullRequest
0 голосов
/ 23 мая 2019

РЕДАКТИРОВАТЬ: этот вопрос был помечен как дубликат некоторыми пользователями.Не уверен, что они прочитали это, прежде чем сделать это.Если кто-то это сделал, уточните, в каком смысле это дубликат.

У меня есть компонент для флажков:

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 Ответ

1 голос
/ 23 мая 2019

Одна возможность - здесь недостаточно информации, чтобы сказать наверняка, - это то, что input.value присутствует, но false (или ложно), так что вы возвращаетесь к value опоре, которая undefined, ив конечном итоге вы устанавливаете checked на undefined на своем входе.

Это приводит к неконтролируемому флажку.

Затем, на следующем проходе, либо input.value, либо props.value имеетизменилось, и вы установили checked к реальному значению, что означает, что теперь это управляемый вход, и реакция выдает предупреждение.

В вашем первоначальном случае вы получите value проп, даже если input.valueявно false или 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.

...