React を使用して、他の個々のチェックボックスを選択および選択解除するチェックボックス(すべて選択/選択解除)を作成しようとすると、少し問題が発生します。 http://facebook.github.io/react/docs/forms.html を読んで、controlledおよびnot-controlled<input>
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 (
<div>
<input type="checkbox" data-id={d.id} checked={d.selected} onChange={this.__changeSelection} />
{d.id}
<br />
</div>
);
});
return (
<form>
<input type="checkbox" ref="globalSelector" onChange={this.__changeAllChecks} />Global selector
<br />
{checks}
</form>
);
},
__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(<Test />, document.getElementById('content'));
「グローバルセレクタ」は期待どおりに機能します。選択すると、他のすべてのチェックが選択されます。問題は、他のチェックボックスのいずれかをクリックしても__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
を渡し、属性検索行を削除します。
__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'));
チェックボックスを扱う場合は、checkedLink
属性を使用できます。次に、別の可能な実装を示します。これにより、グローバルチェックボックスが制御されます(現在の回答では制御されません)。
_var Test = React.createClass({
getInitialState: function() {
return {
globalCheckbox: false,
data: [
{ id: 1, selected: false },
{ id: 2, selected: false },
{ id: 3, selected: false },
{ id: 4, selected: false }
]
};
},
changeCheckForId: function(id,bool) {
this.setState(
{
data: this.state.data.map(function(d) {
var newSelected = (d.id === id ? bool : d.selected);
return {id: d.id, selected: newSelected};
}
)});
},
changeCheckForAll: function(bool) {
this.setState({
globalCheckbox: true,
data: this.state.data.map(function(d) {
return {id: d.id, selected: bool};
})
});
},
linkCheckbox: function(d) {
return {
value: d.selected,
requestChange: function(bool) { this.changeCheckForId(d.id,bool); }.bind(this)
};
},
linkGlobalCheckbox: function() {
return {
value: this.state.globalCheckbox,
requestChange: function(bool) { this.changeCheckForAll(bool); }.bind(this)
};
},
render: function() {
var checks = this.state.data.map(function(d) {
return (
<div>
<input key={d.id} type="checkbox" checkedLink={this.linkCheckbox(d)} />
{d.id}
<br />
</div>
);
}.bind(this));
return (
<form>
<input type="checkbox" checkedLink={this.linkGlobalCheckbox()} />Global selector
<br />
{checks}
</form>
);
},
});
_
変異する状態が深くネストされていない場合、checkedLink=this.linkState("checkboxValue")
をLinkedStateMixin
とともに使用する方が簡単です(この質問の場合がそうです)
Edit:checkedLink
およびvalueLink
は非推奨ですが、Reactの以前のバージョンでは推奨されていました。