反应复选框不切换
Posted
技术标签:
【中文标题】反应复选框不切换【英文标题】:React checkbox doesn't toggle 【发布时间】:2015-12-31 14:43:28 【问题描述】:当我单击复选框时,尽管 onChange 处理程序中的 console.log 指示状态已更改为 false,但复选标记并未消失。另一方面,当通过单独的按钮更改状态时,复选标记会正确地打开和关闭。
export default class TestComponent extends Component
constructor(props)
super(props);
this.state =
is_checked: true
;
this.updateCheckbox = this.updateCheckbox.bind(this);
this.pressButton = this.pressButton.bind(this);
updateCheckbox(event)
event.preventDefault();
this.setState(is_checked: !this.state.is_checked);
console.log(this.state.is_checked); // This logs 'false' meaning the click did cause the state change
console.log(event.target.checked); // However, this logs 'true' because the checkmark is still there
pressButton(event)
event.preventDefault();
this.setState(is_checked: !this.state.is_checked);
render()
return (
<input type="checkbox" onChange=this.updateCheckbox checked=this.state.is_checked ></input>
<button onClick=this.pressButton>change checkbox state using button</button>
);
【问题讨论】:
我知道已经有一段时间了,但接受的答案在某种程度上具有误导性(虽然没有错)。此外,我认为您不应该像在自己的答案中那样使用双向绑定来解决此问题。 【参考方案1】:我想我明白发生了什么。
您单击该按钮,它会切换is_checked
,它会选中或取消选中该框。但这最终会触发复选框的onChange
,这也会切换状态......您实际上已经编写了一个无限循环。虽然,由于 React 批处理/去抖动 setState
操作,您的代码不会锁定您的页面。
试试这个:
钩子 API 的 2019 年更新:
import React, useState from 'react';
const Component = () =>
const [isChecked, setIsChecked] = useState(true);
return (
<div>
<input
type="checkbox"
onChange=(event) => setIsChecked(event.currentTarget.checked)
checked=isChecked
/>
<button onClick=() => setIsChecked(!isChecked)>
change checkbox state using this button
</button>
</div>
);
;
原文:
var React = require("react");
var Component = React.createClass(
getInitialState: function()
return
isChecked: true
;
,
handleCheckboxChange: function(event)
console.log("checkbox changed!", event);
this.setState(isChecked: event.target.checked);
,
toggleIsChecked: function()
console.log("toggling isChecked value!");
this.setState(isChecked: !this.state.isChecked);
,
handleButtonClick: function(event)
console.log("button was pressed!", event);
this.toggleIsChecked();
,
render: function()
return (
<div>
<input type="checkbox" onChange=this.handleCheckboxChange checked=this.state.isChecked />
<button onClick=this.handleButtonClick>change checkbox state using this button</button>
</div>
);
);
module.exports = Component;
请注意,您可以使用 React 的 valueLink 使这段代码更加简洁(在此处阅读更多内容:https://facebook.github.io/react/docs/two-way-binding-helpers.html)
【讨论】:
感谢您的帮助。您提供的代码有同样的问题,但双向绑定的链接很有帮助。更新了我的帖子以显示有效的解决方案。 我忘了在handleCheckboxChange
中添加行,它实际上更新了isChecked
状态——秘密是使用event.target.checked
的值。我更新了代码,仅供参考。这也是一个小提琴:jsfiddle.net/xqb2mxsq
您也可以通过删除“event.preventDefault();”来解决这个问题线。因为这会阻止复选框被选中。因此它将始终是相同的状态。
我知道这是旧的,但问题的根源是e.preventDefault()
。通过阻止 on chagne 的默认行为,即使调用了事件处理程序,您也可以阻止更改发生。所以换句话说,复选框发生了变化,状态发生了变化,然后复选框取消设置,因为它的行为被阻止了。因此,初始代码只需删除 e.preventDefault()
这对我来说也适用于useReducer
。谢谢你。【参考方案2】:
根据 Kabir 提供的链接的双向绑定的 React 文档更改了代码。
为了让它发挥作用,我不得不
使用“React.createClass”而不是“扩展组件”来使用 LinkedStateMixin
import react from 'react/addons'
var TestComponent = React.createClass(
mixins: [React.addons.LinkedStateMixin],
render: function() ....
删除 onChange='updateCheckbox' 并改用 this.linkState。
<input type="checkbox" checkedLink=this.linkState(this.state.is_checked) ></input>
【讨论】:
【参考方案3】:这种行为的原因与 React 的实现细节有关——更具体地说,是 React 如何规范化跨浏览器的更改处理的方式。对于单选和复选框输入,React 使用点击事件代替更改事件。当您在附加的事件处理程序中应用 preventDefault
时,这会阻止浏览器以可视方式更新单选框/复选框输入。有两种可能的解决方法:
stopPropagation
将开关放入setTimeout
:setTimeout(x => this.setState(x), 0, is_checked: !this.state.is_checked);
除非绝对必要,否则最好不要使用preventDefault
。
查看此React Github issue 了解更多信息。
【讨论】:
摆脱 preventDefualt 为我解决了这个问题,使用 react 15 和 typescript 2.2(抱歉格式错误)toggleMyCheckbox(checkboxExent: React.ChangeEvent记住 setState 是异步的,所以:
console.log(event.target.checked);
不应立即反映更改。我处理几个复选框字段的方法:
toggleCheckbox(name, event)
let obj = ;
obj[name] = !this.state[name];
this.setState(obj);
字段:
<input type="checkbox" name="active" value=this.state.active checked=this.state.active onChange=this.toggleCheckbox.bind(this, 'active') />
<input type="checkbox" name="qtype" value=this.state.qtype checked=this.state.qtype onChange=this.toggleCheckbox.bind(this, 'qtype') />
【讨论】:
以上是关于反应复选框不切换的主要内容,如果未能解决你的问题,请参考以下文章