在 React 中设置复选框 "check" 属性

Setting a checkbox "check" property in React

我在使用 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)}
/>

我收到此警告:

Warning: AwesomeComponent is changing an uncontrolled input of type checkbox to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: [some useless docs page I read several times to no avail]

所以我决定创建另一个组件来包装每个单独的复选框,我得到了这个:

<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 值并使用它。但我不知道该怎么做。或许抑制该组件的警告 only?那可能吗?也许还有其他事情可以做?

基本上,defaultChecked 意味着您不想控制输入——它只是用这个值呈现,然后没有办法控制它。此外,不应使用 value,而应使用 checked,因此您的第二个代码应该是正确的。而且你不应该同时使用它们。

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

你能用这种行为创建一个小的 fiddle 吗?

您可以将数据分配给状态,然后使用与单个复选框关联的已选中 属性 将状态设置为

{   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

如果您将复选框的 checked 属性 设置为 nullundefined

就会出现问题

这些是 JS 中的“虚假”值,但是根本 React treats a value of null as if the property was not set。由于复选框的默认状态是未选中的,因此一切都会正常进行。如果你随后将 checked 设置为 true,React 认为 属性 突然出现了!这是 React 认为你从不受控制切换到受控的时候,因为现在 prop checked 存在。

在您的示例中,您可以通过将 checked={this.settings[setting]} 更改为 checked={!!this.settings[setting]} 来消除此警告。注意双爆炸 (!!)。他们会将 nullundefined 转换为 false(并单独保留 true),因此 React 将注册您的 checked 属性 值为false 并从受控表单组件开始。

我也有这个问题,我也读过 docs about controlled-components several times to no avail, but I finally figured it out, so I thought I'd share. Also, since version 15.2.0 正常输入被触发以由设置 value 控制,而复选框被初始化为由设置 checked 控制,不管他们 value 属性,这增加了一点混乱。

A​​moebe 的回答是正确的,但我认为有比双银行 (!!) 更干净的解决方案。只需为 Checkbox 组件的 checked 属性添加值为 falsedefaultProps 属性:

import React from 'react';

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

Checkbox.defaultProps = {
  checked: false
};

export default Checkbox;

如果您选择将 class 组件转换为功能组件,这里有一个使用钩子的答案...

export default Checklist = () => {
  const [listOfItems, setListOfItems] = useState([
    {name: 'bubbles', isChecked: true},
    {name: 'gregory', isChecked: false}
  ]);

  const updateListOfItems = (itemIndex, newsChecked) => {
    const updatedListOfItems = [...listOfItems];
    updatedListOfItems[itemIndex].isChecked = isChecked;
    setListOfItems(updatedListOfItems);
  }

  return (
    {listOfitems.map((item, index) =>
      <index key={index} type="checkbox" checked={item.isChecked} onChange={() => updateListOfItems(index, !item.isChecked)} />
    )}
  )
}