在 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
属性设置为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
属性,并从受控表单组件开始。
我也有这个问题,我也读了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 中设置复选框“检查”属性的主要内容,如果未能解决你的问题,请参考以下文章