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/

React Redux