継続力ですよ。
概要
この辺を読みます。今回はマジで新しく読む。てか長かったので 1 章分だけにする。
State and Lifecycle
ステートとライフサイクルについて、なのですごく大事そうな予感がする。詳細はここ React.Component – React
とりあえず前回作った 1 秒ごとに更新される時計をもう少しやっていくらしい。
function Clock(props) {
return (
<div>
<h1>おはようございました~</h1>
<h2>今は{props.date.toLocaleTimeString()}です~</h2>
</div>
);
}
function tick() {
ReactDOM.render(
<Clock date={new Date()} />,
document.getElementById('kiryu')
);
}
setInterval(tick, 1000);
まあどう考えてもレンダリングは1回にしたいし、そのためには Clock をレンダリング対象にする必要がある。それをステートを使って表現していく。
Function から Class に変更する。
class Clock extends React.Component {
render() {
return (
<div>
<h1>おはようございました~</h1>
<h2>今は{this.props.date.toLocaleTimeString()}です~</h2>
</div>
);
}
}
続く文章はあんまり理解できてはないんだけど、Class として定義することによって、Clock がインスタンスとして扱えるようになる。 これによってローカルでステートを持ったり、ライフサイクルメソッドを使ったりできる(この文は重要っぽい)
で、それに従ってコンストラクタの定義や state を登録していったらこういう形になった(すごく直感的でよい)
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
render() {
return (
<div>
<h1>おはようございました~</h1>
<h2>今は{this.state.date.toLocaleTimeString()}です~</h2>
</div>
);
}
}
function tick() {
ReactDOM.render(
<Clock />,
document.getElementById('kiryu')
);
}
親クラスのコンストラクタを呼びつつ、state に日付情報を持つような形。
この状態でさらに、ライフサイクルメソッドである componentDidMount, componentWillUnmount を刺してみる。
this.props は React 自身が用意し、this.state は特別な意味があるので、このように使える。自分で使いたいものは自分で定義してくださいと。
なのでここでは timer を登録/削除を行ってる。そして timer を通して state を変更することで、時間の更新を実現している。
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = { date: new Date() };
}
// ClockがDOMに挿入されるときに呼ばれる
componentDidMount() {
// 1234 とか不真面目にするとたまに1秒飛んで表示される
this.timerID = setInterval(
() => this.tick(),
1000
);
}
// ClockがDOMから削除されるときに呼ばれる
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
render() {
return (
<div>
<h1>おはようございました~</h1>
<h2>今は{this.state.date.toLocaleTimeString()}です~</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('kiryu')
);
State についての注意点は
setState()を使って更新し、直接更新しないthis.propsやthis.stateは非同期に更新なので、直参照すべきではない。使うのであれば、function でラップして受け付ける。- カウンターとかで関連するかも
setState()では結果がマージされるので、別々の箇所で update していたとしても、入れたものは取り出すことができる- 同じ名前の要素が色々な場所で更新される場合は要注意かも
- データは下のものに伝わる(おそらく子のほうに流れるって意味だと思ってる)
おまけ
知らなかった単語を並べる。
- crucial: 決定的な、非常に重大な
まとめ
いきなりクラスっぽくなって、再利用可能な UI を作るためのノウハウを叩き込まれたような気がします。
またデータフローに関しても割とカプセル化されていつつも、state っていう特殊なやつがよし何やってくれそうなので、利便性は高そうです。
(でも何でもかんでも state に突っ込まれるみたいなパターンもあって、重複するようなキーを更新してバグるとかあると、大変なんだろうなぁ…)
あとは直接編集しないとかも大事ですね。state に関しての注意点は実際に書いてみると忘れそうなので、また見直してみようと思います。