継続力ですよ。
概要
この辺を読みます。今回はマジで新しく読む。てか長かったので 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 に関しての注意点は実際に書いてみると忘れそうなので、また見直してみようと思います。