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

Posted

技术标签:

【中文标题】在 React 中设置复选框“检查”属性【英文标题】:Setting a checkbox "check" property in React 【发布时间】:2016-12-31 09:27:24 【问题描述】:

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

【问题讨论】:

【参考方案1】:

基本上,defaultChecked 表示您不想控制输入 - 它只是使用此值呈现,然后无法控制它。此外,不应使用value,而应使用checked,因此您的第二个代码应该是正确的。而且你不应该同时使用它们。

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

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

【讨论】:

他的问题是因为 this.state.checked 是未定义的,而不是 false。所以这样的东西更安全一点: 【参考方案2】:

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

   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

【讨论】:

【参考方案3】:

如果您将复选框的checked 属性设置为nullundefined,则会出现问题。

这些是 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] 来消除此警告。注意双重爆炸(!!)。他们会将nullundefined 转换为false(并留下true),因此React 将使用false 值注册您的checked 属性,并从受控表单组件开始。

我也有这个问题,我也读了docs about controlled-components 几次都没有用,但我终于弄明白了,所以我想我会分享。此外,由于version 15.2.0 正常输入被触发以通过设置value 来控制,而复选框被初始化为通过设置checked 控制,而不管它们的value 属性如何,这增加了一些混乱。

【讨论】:

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

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

import React from 'react';

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

Checkbox.defaultProps = 
  checked: false
;

export default Checkbox;

【讨论】:

函数声明中只有checked = false怎么样? 是的,这对我来说似乎有点矫枉过正【参考方案5】:

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

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

【讨论】:

以上是关于在 React 中设置复选框“检查”属性的主要内容,如果未能解决你的问题,请参考以下文章

在 firefox 中设置复选框的样式 - 删除检查和边框

如何在打字稿中设置复选框属性

在情节提要中设置时,UISearchBar 不显示范围栏

在 Reactive Forms 复选框中设置默认值

如何在 vba 中设置选中的属性(格式或控制工具箱)

从数组中设置选中的复选框[关闭]