我在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针对该组件?这可能吗?也许还有其他方法可以做?
6条答案
按热度按时间hs1ihplo1#
如果将复选框的
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将使用false
值注册checked
属性,并从一个受控表单组件开始。我也遇到过这个问题,我也读了几遍关于受控组件的文档,但都没有用,但我终于弄明白了,所以我想我应该分享一下。另外,由于version 15.2.0的正常输入是通过设置
value
来触发控制的,而复选框是通过设置checked
来初始化控制的,不管它们的value
属性是什么,这就增加了一点混乱。nzrxty8p2#
Amoebe的答案是正确的,但我认为有一个比double bank(
!!
)更简洁的解决方案,只需为Checkbox组件的checked
prop添加一个值为false
的defaultProps属性即可:cxfofazt3#
基本上,
defaultChecked
意味着你不想控制输入--它只是用这个值渲染,然后就没有办法控制它了。另外,不应该使用value
,而应该使用checked
,所以你的第二个代码应该是正确的。而且你不应该同时使用它们。你能对这种行为做些小小的调整吗?
dphi5xsq4#
如果您选择将类组件转换为函数组件,那么这里是使用钩子的答案...
bxpogfeg5#
您可以将数据分配给状态,然后使用与单个复选框关联的checked属性将状态设置为
状态中的样本数据为
JSFIDDLE
czfnxgou6#
结合其他答案,最后奏效的是: