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

vmpqdwk3  于 2023-01-12  发布在  React
关注(0)|答案(6)|浏览(361)

我在React和复选框方面遇到了一个非常烦人的问题。我正在使用的应用程序需要一个复选框列表,这些复选框代表了在后端保留的设置。有一个选项可以将设置恢复到原始状态
首先,我创建了一个组件,它有一个类似于设置Map的对象,每个设置都有一个键和一个布尔值,因此:

{
    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正在将类型为复选框的非受控输入更改为受控。输入元素不应从非受控切换为受控(反之亦然)。请决定在组件的生存期内使用受控输入元素还是非受控输入元素。详细信息:[* 一些无用的文档页面,我读了几次都没有用 *]
所以我决定创建另一个组件来 Package 每个单独的复选框,我得到了这个:

<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针对该组件?这可能吗?也许还有其他方法可以做?

hs1ihplo

hs1ihplo1#

如果将复选框的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属性,并从一个受控表单组件开始。
我也遇到过这个问题,我也读了几遍关于受控组件的文档,但都没有用,但我终于弄明白了,所以我想我应该分享一下。另外,由于version 15.2.0的正常输入是通过设置value来触发控制的,而复选框是通过设置checked来初始化控制的,不管它们的value属性是什么,这就增加了一点混乱。

nzrxty8p

nzrxty8p2#

Amoebe的答案是正确的,但我认为有一个比double bank(!!)更简洁的解决方案,只需为Checkbox组件的checked prop添加一个值为false的defaultProps属性即可:

import React from 'react';

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

Checkbox.defaultProps = {
  checked: false
};

export default Checkbox;
cxfofazt

cxfofazt3#

基本上,defaultChecked意味着你不想控制输入--它只是用这个值渲染,然后就没有办法控制它了。另外,不应该使用value,而应该使用checked,所以你的第二个代码应该是正确的。而且你不应该同时使用它们。

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

你能对这种行为做些小小的调整吗?

dphi5xsq

dphi5xsq4#

如果您选择将类组件转换为函数组件,那么这里是使用钩子的答案...

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

bxpogfeg5#

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

{   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

czfnxgou

czfnxgou6#

结合其他答案,最后奏效的是:

const [categories, setCategories] = useState(
    [
        {
            field: 'Label 1',
            checked: true
        },
        {
            field: 'Label 2',
            checked: false
        },
        {
            field: 'Label 3',
            checked: false
        }
    ]
)
const updateList = (item, isChecked) => {
    const updatedList = [...categories];
    updatedList[item].checked = isChecked;
    setCategories(updatedList);
}
... in your markup:
{
  categories.map((item, index) =>
    <div key = {item.field}>
      <label>
        <span>{item.field}</span>
        <input key={index}
               type="checkbox"
               checked={item.checked}
               onChange={() => updateList(index, !item.checked)}
         />
      </label>
    </div>
  )
}

相关问题