対象者:私を含むReact初心者
次:ReactJS入門@ES6:ReactRouter編
コンポーネントの作成方法
React.Componentを継承しrenderメソッドを実装したクラスがコンポーネントです。
class Table extends React.Component {
render() {
return (
<div>Table Component</div>
)
}
}
コンポーネントが扱うデータ
1. props
propsはコンポーネントに渡されるデータです。
propsは変更不可のデータです。
<Table name="hoge" />
class Table extends React.Component {
render() {
return (
<div>
<div>Table Component</div>
<div>{this.props.name}</div> // hoge
</div>
)
}
}
2. state
stateはコンポーネント自身のデータです。
stateはconstructorメソッドの内部で初期化します。
class Table extends React.Component {
constructor() {
super();
this.state = {
checked: false
};
}
}
stateの追加や更新にはsetStateメソッドを使用します。
state全体を入れ替える場合は、replaceStateメソッドを使用します。
class Table extends React.Component {
constructor() {
super();
this.state = {
checked: false
};
}
onClick() {
this.setState({ checked: !this.state.checked }); // state.checkeを更新
this.setState({ unchecked: true }); // state.uncheckedを追加
}
}
注意
setStateメソッドを実行後、即時にstateに反映されません。
stateを確実に取得したい場合は、setStateメソッドに関数を渡し、
コールバックで受け取る方法が用意されています。
constructor() {
super();
this.state = {
name: 'NAKAMURA'
};
}
onClick() {
this.setState(
(state, props) => { return {name: 'KINJO'} },
() => { console.log(this.state) } // この時点のstate.nameは [KINJO]
);
console.log(this.state.name); // この時点のstate.nameは [NAKAMURA]
}
コンポーネントのthisのBind
ボタンのクリックイベントを拾いthis.onClickを呼び出す場合、
下記のコードはthis.onClickがundefinedとなり動作しません。
class Table extends React.Component {
onClick() {
// ここにクリック時の処理を書く
}
render() {
return (
<div>
<button onClick={this.onClick}>ボタン</button> // NG
</div>
)
}
}
解決方法は
- コンストラクタ内でbindする
this.onClick = this.onClick.bind(this);
- JSX内でbindする
<button onClick={this.onClick.bind(this)}>...
- ES7のBind Syntaxを使用する
<button onClick={::this.onClick}>...
などがあります。
個人的にはES7のBind Syntaxがシンプルだと思います。
(ES7を使用するリスクを忘れずに)
class Table extends React.Component {
constructor() {
super();
this.onClick = this.onClick.bind(this); // EX:1
}
onClick() {
// ここにクリック時の処理を書く
}
render() {
return (
<div>
<button onClick={this.onClick.bind(this)}>ボタン</button> // EX:2
<button onClick={::this.onClick}>ボタン</button> // EX:3
</div>
)
}
}