我在尝试使用React创建一个复选框来选择和取消选择其他单独的复选框(选择/取消选择全部)时遇到了一些问题.我已经阅读了http://facebook.github.io/react/docs/forms.html,发现受控和非受控 s 之间存在差异.我的测试代码如下:
var Test = React.createClass({ getInitialState: function() { return { data: [ { id: 1, selected: false }, { id: 2, selected: false }, { id: 3, selected: false }, { id: 4, selected: false } ] }; }, render: function() { var checks = this.state.data.map(function(d) { return (); }, __changeSelection: function(e) { var id = e.target.getAttribute('data-id'); var state = this.state.data.map(function(d) { return { id: d.id, selected: (d.id === id ? !d.selected : d.selected) }; }); this.setState({ data: state }); }, __changeAllChecks: function(e) { var value = this.refs.globalSelector.getDOMNode().checked; var state = this.state.data.map(function(d) { return { id: d.id, selected: value }; }); this.setState({ data: state }); } }); React.renderComponent({d.id}); }); return (
"全局选择器"按预期工作:选中后,将选中所有其他检查.问题是,__changeSelection()
当单击其他复选框之一时,不会触发处理程序.
我不知道做这项工作的正确方法是什么.也许React模型不是模拟这种交互的最佳模型?我能做什么?
提前致谢
在你的render
功能,范围this
为checks
映射功能是不同的render
,这是你需要的范围__changeSelection
,所以this.__changeSelection
不会找到一个__changeSelection
属性.如果您添加.bind(this)
到映射函数的最后,你可以绑定它的范围相同this
的render
:
var checks = this.state.data.map(function(d) {
return (
<div>
<input type="checkbox" data-id={d.id} checked={d.selected} onChange={this.__changeSelection} />
{d.id}
<br />
</div>
);
}.bind(this));
在旁注中,我只是将其传递id
给处理函数而不是分配数据属性.这将消除在处理程序中找到该元素的需要:
var checks = this.state.data.map(function(d) {
return (
<div>
<input type="checkbox" checked={d.selected} onChange={this.__changeSelection.bind(this, d.id)} />
{d.id}
<br />
</div>
);
}.bind(this));
然后更新您的__changeSelection
函数以传入id
第一个arg并删除属性查找行:
__changeSelection: function(id) {
var state = this.state.data.map(function(d) {
return {
id: d.id,
selected: (d.id === id ? !d.selected : d.selected)
};
});
this.setState({ data: state });
}
以下是一个将它们放在一起的示例,以及一个jsfiddle供您试用:
/** @jsx React.DOM */
var Test = React.createClass({
getInitialState: function() {
return {
data: [
{ id: 1, selected: false },
{ id: 2, selected: false },
{ id: 3, selected: false },
{ id: 4, selected: false }
]
};
},
render: function() {
var checks = this.state.data.map(function(d) {
return (
<div>
<input type="checkbox" checked={d.selected} onChange={this.__changeSelection.bind(this, d.id)} />
{d.id}
<br />
</div>
);
}.bind(this));
return (
<form>
<input type="checkbox" ref="globalSelector" onChange={this.__changeAllChecks} />Global selector
<br />
{checks}
</form>
);
},
__changeSelection: function(id) {
var state = this.state.data.map(function(d) {
return {
id: d.id,
selected: (d.id === id ? !d.selected : d.selected)
};
});
this.setState({ data: state });
},
__changeAllChecks: function() {
var value = this.refs.globalSelector.getDOMNode().checked;
var state = this.state.data.map(function(d) {
return { id: d.id, selected: value };
});
this.setState({ data: state });
}
});
React.renderComponent(<Test />, document.getElementById('content'));