单选按钮中的 onChange 导致状态中的值发生意外更改
Posted
技术标签:
【中文标题】单选按钮中的 onChange 导致状态中的值发生意外更改【英文标题】:onChange in radio button causing undesired change of values in the state 【发布时间】:2021-12-16 21:26:06 【问题描述】:const [toggleValue, setToggleValue] = useState();
..
..
Items.map((item) => (
<Card onClick=() => setToggleValue(item.id) key=item.id>
<CardHeader text=item.text />
<Collapse isOpen=toggleValue=== item.id>
<CardBody>
<FormGroup>
<CustomInput value="1" type="radio" id="yes" onChange=handleOptionChange(item.id, '1') />
<CustomInput value="2" type="radio" id="yes" onChange=handleOptionChange(item.id, '2') />
</FormGroup>
</CardBody>
</Collapse>
</Card>
它按预期工作,但是当我使用单选按钮在这些卡片中选择一个选项时,它会自动折叠当前卡片并展开第一张卡片。在进行单选按钮选择时触发的 handleOptionChange 函数也使用 useState 更改状态中的不同值:
const handleOptionChange = (name, value) => () =>
const Item = name;
const numericValue = Number(value);
setFormData(
...data,
id: Item,
vote: numericValue,
);
;
【问题讨论】:
【参考方案1】:handleOptionChange(item.id, '1') 不应在 onChange 上直接调用
const [toggleValue, setToggleValue] = useState();
..
..
Items.map((item) => (
<Card onClick=() => setToggleValue(item.id) key=item.id>
<CardHeader text=item.text />
<Collapse isOpen=toggleValue=== item.id>
<CardBody>
<FormGroup>
<CustomInput value="1" type="radio" id="yes" onChange=()=>handleOptionChange(item.id, '1') />
<CustomInput value="2" type="radio" id="yes" onChange=()=>handleOptionChange(item.id, '2') />
</FormGroup>
</CardBody>
</Collapse>
</Card>
【讨论】:
【参考方案2】:改变这个
<CustomInput value="1" type="radio" id="yes" onChange=handleOptionChange(item.id, '1') />
进入这个
<CustomInput value="1" type="radio" id="yes" onChange=() => handleOptionChange(item.id, '1') />
原因,正确的原因
对于没有() =>
的onChange=() => ....
,同样是在组件挂载时运行该函数,无需等待任何用户操作。
您可以通过警报进行测试
onChange=() => alert('will run only when user change')
...
onChange=alert('Will not wait for user and run when component mount')
【讨论】:
当我这样做时,handleOptionChange 函数不会在单击单选按钮时调用,并且单选值未设置为状态。我注意到单选按钮未正确单击。【参考方案3】:javascript 事件将冒泡到最近的具有事件监听器的父级
所以在这种情况下,当您单击单选按钮时,它实际上会触发一个 onClick 事件,该事件会冒泡到 Card 组件的 onClick 事件侦听器,从而调用 onClick setToggleValue 函数
您可以将onClick=(event)=>event.stopPropagation()
添加到您的 CustomIInput 组件以防止这种行为
【讨论】:
我得到 event is deprecated 错误,在 VSCode 中划掉了“event”这个词。 抱歉应该是onClick=(event)=>event.stopPropagation()
这应该解决 Card collapsing 问题,其他两个答案应该解决错误 value 问题
谢谢,这解决了卡崩溃的问题。但是,当我使用其他两个答案时,状态值没有得到更新,并且单选按钮没有正确单击。以上是关于单选按钮中的 onChange 导致状态中的值发生意外更改的主要内容,如果未能解决你的问题,请参考以下文章
onClick和onChange不会在reactjs中的safari单选按钮上触发
如何在UnChecked时触发单选按钮的OnChange事件