在 React 中设置复选框“check”属性

IT技术 reactjs checkbox default-value
2021-04-07 17:37:33

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

5个回答

如果您将checked复选框属性设置null,则会出现问题undefined

这些是 JS 中的“假”值,但是React 将值null视为根本没有设置属性由于复选框的默认状态未选中,所以一切都会正常工作。如果你然后设置checkedtrueReact 认为该属性突然存在!这是当你从不受控制切换到受控制的 React 图形时,因为现在 propchecked存在。

在您的示例中,您可以通过更改checked={this.settings[setting]}checked={!!this.settings[setting]}. 注意双刘海 ( !!)。他们将转换nullundefinedfalse(离开true单独的),等react过来将你的注册checked用的value属性false,并以受控的表单组件开始。

我也有这个问题,我也多次阅读有关受控组件文档无济于事,但我终于想通了,所以我想我会分享。此外,由于版本 15.2.0正常输入被触发以由 setting 控制value,而复选框被初始化为由 setting 控制checked,无论其value属性如何,这增加了一些混乱。

浪费了一个多小时,因为我认为由于 React 的一条非常具体的警告消息,我理解了这个问题。不。这是一个未定义的变量,后来被定义。谢谢你。
2021-05-28 17:37:33
我对这个答案赞不绝口。我有条件地添加和删除checked属性本身,这在纯 HTML 时代是一种很好的做法。我花了二十分钟不明白为什么会出现这个错误信息。ReactJS 错误消息确实应该有一个特殊情况,承认 HTML 复选框输入的不一致怪异,以便其他人也不会碰到这个问题。
2021-05-30 17:37:33
我也没有意识到复选框是由 'checked' 属性而不是 'value' 控制的。在我发现这篇文章之前,我得到了一些奇怪的行为。谢谢!reactjs.org/docs/forms.html
2021-06-05 17:37:33
令人难以置信的答案:) 这是一个我不知道的好技巧(使用双爆炸立即转换为布尔值)
2021-06-17 17:37:33

Amoebe 的答案是正确的,但我认为有比双银行 ( !!)更清洁的解决方案只需Checkbox 组件的 prop添加一个defaultProps属性值falsechecked

import React from 'react';

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

Checkbox.defaultProps = {
  checked: false
};

export default Checkbox;
仅仅{checked = false}在函数声明中怎么样?
2021-05-24 17:37:33

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

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

你能用这种行为创造一个小小提琴吗?

他的问题是因为 this.state.checked 是未定义的,而不是错误的。所以像这样更安全一点: <input type="checkbox" checked={!!this.state.checked} onChange={this.onChangeAction.bind(this)} />
2021-06-08 17:37:33

如果您选择将类组件转换为功能组件,这是使用钩子的答案...

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)} />
    )}
  )
}

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

{   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