React.js で親コンポーネントと子コンポーネントが連携するシンプルなサンプルを書いてみた。
元ネタは、書籍 『入門React (Developing a React Edge)』 のサンプルコード bleeding-edge-sample-app/client/app/components/answers at master · backstopmedia/bleeding-edge-sample-app · GitHub で、ここから余計なものを省いてシンプルなコードにしたもの。
サンプルのスクリーンショット。
あらかじめ、子コンポーネントの onChanged プロパティに、親コンポーネントのコールバック関数を設定しておいて、子コンポーネントのイベントが発生したら、子コンポーネントから this.props.onChanged を呼び出すことで、親コンポーネントのコールバック関数が呼び出される仕組み。
サンプルコード。
<!DOCTYPE html>
<html>
<head>
<title>React.js sample: Parent Component and Child Components</title>
<meta charset="UTF-8">
<script src="http://fb.me/react-0.12.2.js"></script>
<script src="http://fb.me/JSXTransformer-0.12.2.js"></script>
</head>
<body>
<script type="text/jsx">
// 子コンポーネント (ラジオボタン)
var Child = React.createClass({
propTypes: {
id: React.PropTypes.string,
name: React.PropTypes.string.isRequired,
label: React.PropTypes.string.isRequired,
value: React.PropTypes.string.isRequired,
checked: React.PropTypes.bool
},
getDefaultProps: function(){
return {
checked: false
};
},
getInitialState: function(){
return {
checked: !!this.props.checked
};
},
componentWillReceiveProps: function(nextProps){
console.log("Child#componentWillReceiveProps: " + nextProps.id);
if(nextProps.checked !== undefined) {
this.setState({
checked: nextProps.checked
});
}
},
handleChanged: function(e){
console.log("Child#handleChanged: " + this.props.value);
var checked = e.target.checked;
this.setState({checked: checked});
if(checked){
// 親コンポーネントのコールバック関数を呼び出す
this.props.onChanged.apply(this.props, [this.props.value]);
}
},
render: function(){
console.log("Child#render: " + this.props.id);
return (
<div className="radio">
<label>
<input type="radio"
name={this.props.name}
id={this.props.id}
value={this.props.value}
checked={this.state.checked}
onChange={this.handleChanged} />
{this.props.label}
</label>
</div>
);
}
});
// 親コンポーネント
var Parent = React.createClass({
propTypes: {
value: React.PropTypes.string,
choices: React.PropTypes.array.isRequired
},
getInitialState: function(){
return {
id: "multiple-choice",
value: this.props.value
};
},
// 子コンポーネントから呼び出すためのコールバック関数
handleChanged: function(value){
console.log("Parent#handleChanged: " + value);
this.setState({value: value});
},
renderChoices: function(){
console.log("Parent#renderChoices: " + this.state.id);
var list = [];
for(var i=0; i<this.props.choices.length; i++){
var choice = this.props.choices[i];
list.push(Child({
id: "choice-" + i,
name: this.state.id,
label: choice,
value: choice,
checked: this.state.value === choice,
onChanged: this.handleChanged // 子コンポーネントの onChanged プロパティにコールバック関数をセット
}));
}
return list;
},
render: function(){
console.log("Parent#render: " + this.state.value);
return (
<div className="form-group">
<label className="survey-item-label" htmlFor={this.state.id}>{this.props.label}</label>
<div className="survey-item-content">
{this.renderChoices()}
</div>
<div>{this.state.value && this.state.value + "が選択されました"}</div>
</div>
);
}
});
React.render(
<Parent choices={["aaa","bbb","ccc"]}></Parent>,
document.getElementById("example")
);
</script>
<div style="margin: 50px;">React.js sample: Parent Component and Child Components</div>
<div style="margin: 50px;" id="example"></div>
<div style="margin: 50px;">ref. <a href="https://github.com/backstopmedia/bleeding-edge-sample-app/tree/master/client/app/components/answers">bleeding-edge-sample-app/client/app/components/answers at master · backstopmedia/bleeding-edge-sample-app · GitHub</a></div>
</body>
</html>
- React.js sample: Parent Component and Child Components (Webブラウザでの確認用サンプルコード)
- 入門React (Developing a React Edge) (Book_Developing_a_React_Edge - MemoWiki)
- [ヅ] React.js でシンプルなサンプルを書いてみた (2015-02-16)
- [ヅ] React.js はコンポーネントの開始タグと終了タグの間のすべての子ノードを this.props.children という配列にセットする (2015-06-02)
tags: react.js javascript
Posted by NI-Lab. (@nilab)