React (+ Redux) ライフサイクル
公式を読んでいきます! 各セクション TL;DR で
State and Lifecycle
React コンポーネントの状態とライフサイクルの概念について。
Classで書く
React.Component
にClockクラスを拡張する。
関数の本体を render()
メソッドに定義していて、this.props
で値を取得して render()
。
render()
メソッドは、更新が行われるたびに呼び出される。
下記の例では、<Clock />
が、同じDOMノードにレンダリングする限り、
そのClockクラスのインスタンスは1つだけ使用される。
class Clock extends React.Component { render() { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.props.date.toLocaleTimeString()}.</h2> // this.props で取得 </div> ); } } function tick() { ReactDOM.render( <Clock date={new Date()} />, document.getElementById('root') ); } setInterval(tick, 1000);
Local state を使う
this.props.date と this.state.date して render() する方法
class Clock extends React.Component { constructor(props) { super(props); this.state = {date: new Date()}; } render() { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.state.date.toLocaleTimeString()}.</h2> </div> ); } } ReactDOM.render( <Clock />, document.getElementById('root') );
ライフサイクルメソッドをクラスに追加する
多くのコンポーネントを持つアプリケーションでは、コンポーネントが破壊されたときにリソースを解放することが非常に重要だ
class Clock extends React.Component { constructor(props) { super(props); this.state = {date: new Date()}; } // DOMにレンダリングされた後にフックが行われる componentDidMount() { // タイマーセット(マウント処理) this.timerID = setInterval( // this.でアクセスしてtimerID を保存 () => this.tick(), 1000 ); } componentWillUnmount() { // タイマークリア(アンマウント処理) clearInterval(this.timerID); } tick() { this.setState({ date: new Date() }); } render() { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.state.date.toLocaleTimeString()}.</h2> </div> ); } } ReactDOM.render( <Clock />, // Clockコンポーネントのコンストラクタを呼び出す document.getElementById('root') );
状態を正しく使用する
// wrong this.state.comment = 'Hello'; // Correct this.setState({comment: 'Hello'});
状態の更新を非同期で行う
// Wrong this.setState({ counter: this.state.counter + this.props.increment, }); // Correct // 第1引数がstate, 第2引数が更新後のオブジェクト等 this.setState((prevState, props) => ({ counter: prevState.counter + props.increment }));
状態の更新を適用
constructor(props) { super(props); this.state = { posts: [], comments: [] }; } componentDidMount() { fetchPosts().then(response => { this.setState({ posts: response.posts }); }); fetchComments().then(response => { this.setState({ comments: response.comments }); }); }
データフローダウン
これは、通常、「トップダウン」または「一方向」データフローと呼ばれます。すべての状態は常に特定のコンポーネントによって所有され、 その状態から派生したデータまたはUIはツリー内のコンポーネントの「下」にしか影響を与えません。 コンポーネントツリーを小道具の滝として想像すると、各コンポーネントの状態は、任意の点でそれを結合する追加の水源のようですが、流れ落ちます。
function FormattedDate(props) { return <h2>It is {props.date.toLocaleTimeString()}.</h2>; } class Clock extends React.Component { constructor(props) { super(props); this.state = {date: new Date()}; } componentDidMount() { this.timerID = setInterval( () => this.tick(), 1000 ); } componentWillUnmount() { clearInterval(this.timerID); } tick() { this.setState({ date: new Date() }); } render() { return ( <div> <h1>Hello, world!</h1> <FormattedDate date={this.state.date} /> </div> ); } } ReactDOM.render( <Clock />, document.getElementById('root') );
React.Component
コンポーネントライフサイクル ライフサイクルメソッドの公式チートシート http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/
コンポーネントのインスタンスを作成してDOMに挿入するときに呼ばれるメソッドについて
constructor() static getDerivedStateFromProps() render() componentDidMount()
※ 非同期レンダリングのライフサイクルについて https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html
状態の変更(更新)
static getDerivedStateFromProps() shouldComponentUpdate() render() getSnapshotBeforeUpdate() componentDidUpdate()
アンマウント
コンポーネントがDOMから削除されるとき componentWillUnmount()
一般的に使われるライフサイクルメソッド
https://reactjs.org/docs/react-component.html#reference
参考: https://reactjs.org/docs/react-component.html
Redux Todos Example
公式: https://redux.js.org/basics/example-todo-list GitHub: https://github.com/reduxjs/redux/tree/master/examples/todos
Redux Todos Example を読み解く 参考: https://intheweb.io/react-redux-todos/