LoginSignup
1
1

More than 5 years have passed since last update.

【Part3】はじめてのReact勉強メモ

Posted at

はじめに

前回の続きです。

公式チュートリアルのComponents and Props
からやっていきます。

業務時間中にちまちま書いているんですが、なんとかモチベーションを落とさずに継続できています・・・!

やってみる

Components and Props

Vue.jsでもやるコンポーネント分割と、コンポーネント間のデータの受け渡しのあたりの話ですね。
Part1でも若干触れましたが、基本的にclassで定義するようです。babelを使わない場合はfuntionで定義してもいいそうですが、classの方が色々と都合が良いとのこと。

こんな感じで使うんですね。コンポーネントを埋め込む際は<Welcome>のように先頭を大文字にするのがお作法のようです。

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

class App extends extends React.Component {
  render() {
    return (
      <div>
        <Welcome name="Tanaka" />
        <Welcome name="Sato" />
      </div>
    )
  }
}

ReactDOM.render(
  <App/>,
  document.getElementById('root)
)

他には1コンポーネントが複雑化した際の分割方法が書かれてありましたが、Vueと同じような感じですね。

また、受け渡されるpropsはreadonlyだとのことです。これもVue.jsでは親のコンポーネントの値を変更するのは推奨されていませんでしたし、一緒ですね。

State and Lifecycle

これまではReactDOM.render()によって描画を更新する方法しか知りませんでしたが、この章ではそれ以外の方法を教えてくれるそうです。

時計のコンポーネントを作るとしたら、これまでの知見だけでは

function Clock(props) {
  return (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {props.date.toLocaleTimeString()}.</h2>
    </div>
  );
}

function tick() {
  ReactDOM.render(
    <Clock date={new Date()} />,
    document.getElementById('root')
  );
}

setInterval(tick, 1000);

こんな感じになりますが、これだと毎回ReactDOM.render()でアプリ全体の描画を更新することになってしまいます。
本当はClockの内部で時刻を勝手に更新していくような作りにしたい・・・。

そこで、stateをコンポーネントに定義しましょう。Vueで言うところのdataですね。
stateを使うとこんな感じにかけるそうです。

DOMの定義部分ではthis.stateでコンポーネントのstate内の値を見にいって、constructor内で渡されたpropsstateに保存するような動作にしています。

Vueで言い換えるとconstructor()created()statedataのイメージですね。

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')
);

続いて、時刻を更新する処理を作ります。VueだとmountedsetIntervalを入れてbeforeDestroyclearIntervalするイメージですかね。

こんな感じにかけるそうです。想像通りですね。一度constructorstateを定義すれば、クラスにプロパティを足したりするのは自由らしいです。以下の例ではtimerIDを後から追加していますね。

stateの更新はsetStateを使う必要があるそうです。。Vueだとmethodsの中にコンポーネント内関数を定義していましたが、reactだとtick()を定義しているようにクラス内に自由に定義して良さそうですね。もちろんReact.Componentの関数をオーバーライドしないように注意しなければいけ無さそうですが。

処理が呼ばれる順番はコメントに書きました。

class Clock extends React.Component {
  // 2
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  // 4
  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  // 6
  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  // 5
  tick() {
    this.setState({
      date: new Date()
    });
  }

  // 3
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

// 1
ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

stateを変更する際はsetState()を使う必要がありますが、statepropsは非同期で更新されるので以下のように書く必要があると。

// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});

// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

setStateはシャローマージ?なので、既存のプロパティを壊さず一部を置換したりできると。

こんな感じに書いても、this.setState({comments})state.postsが消えることは無いと説明しています。

  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
      });
    });
  }

残りの部分は、stateがコンポーネント内にカプセル化していて、propsは常に子コンポーネントに流れる単方向データフローであると説明しています。この辺りもVueと同じですね。

終わりに

今回はコンポーネントとライフサイクルを学びましたが、なんとなくReactでアプリを作る道筋が見えてきました。基本的な概念はVueと変わらないですし、意外とすんなり受け入れられそうですね。次回はHandling Eventsからやっていきます。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1