2016-08-24 2 views
9

У меня очень неприятная проблема с React и checkboxes. Для приложения, с которым я работаю, требуется список флажков, представляющих настройки, которые сохраняются в фоновом режиме. Существует возможность восстановить настройки в исходное состояние.Установка флажка "check" свойство в React

Сначала я создал компонент, у которого есть объект, такой как карта настроек. Каждый параметр имеет ключ и логическое значение. Следовательно:

{ 
    bubbles: true, 
    gregory: false 
} 

должен быть представлен в виде:

<input type="checkbox" value="bubbles" checked="checked" /> 
<input type="checkbox" value="gregory" /> 

Теперь, кажется, React не знает о том, как предполагается, флажок, чтобы работать. Я не хочу устанавливать значения флажков, я хочу свойство «checked».

Тем не менее, если я пытаюсь что-то вроде этого:

<input 
    type="checkbox" 
    value={setting} 
    checked={this.settings[setting]} 
    onChange={this.onChangeAction.bind(this)} 
/> 

Я получаю это предупреждение:

Внимание: AwesomeComponent меняется неконтролируемый вход типа флажок, чтобы управляться. Элементы ввода не должны переключаться с неконтролируемого на управляемый (или наоборот). Решите, используя управляемый или неконтролируемый входной элемент для времени жизни компонента. Подробнее: [некоторая бесполезна страница документы я прочитал несколько раз без толка]

Поэтому я решил создать еще один компонент, чтобы обернуть каждый отдельный флажок, и я получил это:

<input 
    type="checkbox" 
    checked={this.state.checked} 
    onChange={this.onChangeAction.bind(this)} 
/> 

Теперь checked является собственностью, находящейся непосредственно в моем штате.

Это дает такое же предупреждение, так что я попытался с помощью defaultChecked:

<input 
    type="checkbox" 
    defaultChecked={this.state.checked} 
    onChange={this.onChangeAction.bind(this)} 
/> 

что делает предупреждение исчезает, но теперь она не может сбросить значение checked по умолчанию. Поэтому я попытался сыграть с методом componentWillReceiveProps, таким образом, я уверен, что мое состояние правильно, this.state.checked верен и компонент снова отображает.

И это действительно так. Но флажок остается прежним. На данный момент я оставил это уродливое предупреждение, и я использую checked. Как я могу исправить это, чтобы предупреждение исчезло?

Я думал, что, возможно, есть способ принудительно повторно отобразить компонент, поэтому он захватывает новое значение defaultChecked и использует его. Но я не знаю, как это сделать. Возможно, подавить предупреждение только для этого компонента? Это возможно? Возможно, есть что-то еще, что можно сделать?

ответ

28

проблема возникает, если вы установите checked свойство вашего флажка в null или undefined.

Это «ложные» значения в JS, но вообще React treats a value of null as if the property was not set. Так как состояние по умолчанию флажка не отмечено, все будет работать нормально. Если вы затем установили checked в true React считает, что недвижимость внезапно появилась! Это когда React показывает, что вы переключились с неконтролируемого на контролируемый, так как теперь существует поддержка checked.

В вашем примере вы можете избавиться от этого предупреждения, изменив checked={this.settings[setting]} на checked={!!this.settings[setting]}. Обратите внимание на двойной удар (!!). Они преобразуют null или undefined в false (и оставьте только true), поэтому React зарегистрирует ваше имущество checked со значением false и начнется с контролируемого компонента формы.

У меня тоже была эта проблема, и я тоже читал docs about controlled-components серверное время безрезультатно, но я, наконец, понял это, поэтому я решил поделиться с вами. Кроме того, начиная с version 15.2.0 нормальные входы запускаются для управления, устанавливая value, в то время как флажки инициализируются как управляемые установкой checked, независимо от их свойства value, что немного добавило к путанице.

+2

За час потраченного впустую, потому что я думал, что я понял вопрос из-за весьма специфического предупреждающего сообщение от React. Неа. Это неопределенная переменная, определяемая позже. Спасибо. – Don

+2

Я не могу дождаться этого ответа достаточно. Я условно добавлял и удалял сам атрибут 'checked', что было хорошей практикой в ​​днях HTML-файлов в простой jane. Я потратил двадцать минут на недоумение, почему произошло это сообщение об ошибке. Сообщение об ошибке ReactJS действительно должно иметь специальный случай, подтверждающий несогласованность странности, которая является вкладкой HTML-кода, так что другие не сталкиваются с этим. –

+1

Невероятный ответ :) И это хороший трюк, о котором я не знал (используя двойной удар, чтобы мгновенно привести к логическому значению) –

1

В принципе, defaultChecked означает, что вы не хотите управлять вводом - он просто отображает это значение, а затем нет возможности его контролировать. Также не следует использовать value, но checked, поэтому ваш второй код должен быть правильным. И вы не должны использовать их одновременно.

<input 
    type="checkbox" 
    checked={this.state.checked} 
    onChange={this.onChangeAction.bind(this)} 
/> 

Можете ли вы создать небольшую скрипку с таким поведением?

0

Вы можете назначить свои данные в состоянии, а затем сделать использование проверяемого имущества, связанного с отдельным флажком, чтобы установить состояние как

{ this.state.data.map(function(item, index) { 
     return (

     <input type="checkbox" checked={item.value} onChange={this.handleChange.bind(this, index)}/> 

    ); 
    }.bind(this)) 
    } 

образца данных в состояние, как

data: [{name:'bubbles', value: true}, {name:'gregory', value: false}] 

JSFIDDLE

4

Ответ Амебе правильный, но я думаю, что есть более чистое решение, чем двойной банк (!!). Просто добавьте defaultProps свойства со значением false для checked подпорки компонента Checkbox:

import React from 'react'; 

const Checkbox = ({checked}) => (
    <div> 
     <input type="checkbox" checked={checked} /> 
    </div> 
); 

Checkbox.defaultProps = { 
    checked: false 
}; 

export default Checkbox; 
Смежные вопросы