反应复选框不发送 onChange
Posted
技术标签:
【中文标题】反应复选框不发送 onChange【英文标题】:React Checkbox not sending onChange 【发布时间】:2014-12-24 07:08:01 【问题描述】:TLDR:使用 defaultChecked 而不是选中,工作 jsbin。
尝试设置一个简单的复选框,当它被选中时会划掉它的标签文本。由于某种原因,当我使用该组件时,handleChange 没有被触发。谁能解释我做错了什么?
var CrossoutCheckbox = React.createClass(
getInitialState: function ()
return
complete: (!!this.props.complete) || false
;
,
handleChange: function()
console.log('handleChange', this.refs.complete.checked); // Never gets logged
this.setState(
complete: this.refs.complete.checked
);
,
render: function()
var labelStyle=
'text-decoration': this.state.complete?'line-through':''
;
return (
<span>
<label style=labelStyle>
<input
type="checkbox"
checked=this.state.complete
ref="complete"
onChange=this.handleChange
/>
this.props.text
</label>
</span>
);
);
用法:
React.renderComponent(CrossoutCheckbox(text: "Text Text", complete: false), mountNode);
解决方案:
使用 checked 不会让底层值发生变化(显然),因此不会调用 onChange 处理程序。切换到 defaultChecked 似乎可以解决这个问题:
var CrossoutCheckbox = React.createClass(
getInitialState: function ()
return
complete: (!!this.props.complete) || false
;
,
handleChange: function()
this.setState(
complete: !this.state.complete
);
,
render: function()
var labelStyle=
'text-decoration': this.state.complete?'line-through':''
;
return (
<span>
<label style=labelStyle>
<input
type="checkbox"
defaultChecked=this.state.complete
ref="complete"
onChange=this.handleChange
/>
this.props.text
</label>
</span>
);
);
【问题讨论】:
首先,为什么不添加一个只执行this.setState(checked: !this.state.checked)
的onChange 比必须存储一个值更容易。然后检查属性中的三元运算符:checked=this.state.checked ? 'checked': null
这就是它开始的方式,但它似乎从未更新。所以我开始到处弄乱它来调试没有被解雇的东西。理想情况下,完成后会回到最简单的形式:)
假设你的 mountNode 是一个实际的 dom 节点,你必须使用this.refs.complete.getDOMNode().checked
。见小提琴jsfiddle.net/d10xyqu1
他可以只使用状态而不是获取 dom 节点:jsfiddle.net/d10xyqu1/1 它工作正常,你一定打错了。
忽略 TLDR 注释 - defaultChecked 并不总是答案
【参考方案1】:
要获得复选框的选中状态,路径将是:
this.refs.complete.state.checked
另一种方法是从传递给handleChange
方法的事件中获取它:
event.target.checked
【讨论】:
handleChange 永远不会被调用,无论您单击复选框还是标签,handleChange 都不会被调用:(. 尝试在您的输入中使用 defaultChecked=this.state.complete 而不是“checked”。 就是这样......一直在寻找和四处寻找。如果其他人也遇到此问题,将使用完整的工作答案更新问题。 但是为什么 - 有同样的问题,但你应该使用checked
控制组件:/
设置checked
表示状态在组件外部进行管理。当用户点击时,没有什么可以调用handleChange
,因为没有更新状态。相反,您需要监听 onClick
并在那里触发状态更新。【参考方案2】:
在这种情况下最好不要使用 refs。使用:
<input
type="checkbox"
checked=this.state.active
onClick=this.handleClick
/>
有一些选择:
checked
与 defaultChecked
前者会同时响应状态变化和点击。 后者会忽略状态变化。
onClick
与 onChange
前者总是会在点击时触发。
如果checked
属性存在于input
元素上,则后者不会在点击时触发。
【讨论】:
我正在使用 React 16.13.1,如果没有 onChange 属性,您将无法提供选中的属性。如果我同时定义两者,并使选中的属性响应输入,那么每次单击该框时我都会获得所需的行为和 onChange 触发器。所以我认为这个答案已经过时了。【参考方案3】:如果您有一个如下所示的handleChange
函数:
handleChange = (e) =>
this.setState(
[e.target.name]: e.target.value,
);
您可以创建一个自定义的onChange
函数,使其像文本输入一样工作:
<input
type="checkbox"
name="check"
checked=this.state.check
onChange=(e) =>
this.handleChange(
target:
name: e.target.name,
value: e.target.checked,
,
);
/>
【讨论】:
不是handleChange
on input
应该是this.handleChange
?
你犯了一个小错误 -> [e.target.name]: e.target.checked
@Haikel 如果您有一个仅处理复选框输入的 handleChange 函数,那将是正确的,但是如果您注意到在第二个代码块中我们在箭头函数中调用 handleChange
并且将target.value
设置为e.target.checked
(本质上是创建一个虚假事件)。这样做是为了使相同的 handleChange 函数也可以用于文本输入,因为这就是它们在更改事件中传递值的方式。【参考方案4】:
在您不想在输入 DOM 上使用 onChange 处理程序的场景中,您可以使用 onClick
属性作为替代方案。 defaultChecked
,条件可能会为 v16 IINM 留下固定状态。
class CrossOutCheckbox extends Component
constructor(init)
super(init);
this.handleChange = this.handleChange.bind(this);
handleChange(target)
if (target.checked)
target.removeAttribute('checked');
target.parentNode.style.textDecoration = "";
else
target.setAttribute('checked', true);
target.parentNode.style.textDecoration = "line-through";
render()
return (
<span>
<label style=textDecoration: this.props.complete?"line-through":"">
<input type="checkbox"
onClick=this.handleChange
defaultChecked=this.props.complete
/>
</label>
this.props.text
</span>
)
我希望这对将来的某人有所帮助。
【讨论】:
【参考方案5】:如果有人正在寻找通用事件处理程序,可以或多或少地使用以下代码(假设为每个输入设置了 name 属性):
this.handleInputChange = (e) =>
item[e.target.name] = e.target.type === "checkbox" ? e.target.checked : e.target.value;
【讨论】:
【参考方案6】:使用 defaultChecked 时,onChange 不会在移动设备上调用 handleChange。作为替代方案,您可以使用 onClick 和 onTouchEnd。
<input onClick=this.handleChange onTouchEnd=this.handleChange type="checkbox" defaultChecked=!!this.state.complete />;
【讨论】:
【参考方案7】:在material ui中,checkbox的状态可以取为
this.refs.complete.state.switched
【讨论】:
以上是关于反应复选框不发送 onChange的主要内容,如果未能解决你的问题,请参考以下文章