JavaScript
reactjs
es2015

ReactのStateとPropsの違いについて ~0からreact習得記 day 08~

これまでのreact習得記は、こちらから閲覧できます。

はじめに

株式会社VRizeでインターンとして勤務しているryo_tです。
短期目標に「1ヶ月でReactのUIを開発できるように」と伝えられたので、Reactはほとんど未経験ですが一歩一歩頑張って行きます。

目的

ReactのPropsとStateの違いを理解すること

Componentにおける値の受け渡し方について

  • ReactのComponentの特徴としてComponentがツリー構造になり親と子ができることが挙げられます。
  • ES2015のクラスの継承機能を利用し、React.Component を継承することで状態を持つことが出来ます。この状態はクラス内のメソッドから変更することが出来ます。
  • reduxを使用する際のStateの扱いとの対比から、クラスで実現するStateをLocal Stateと呼ぶこともあるようです。
  • Componentがデータを受け取ったりPropsが存在します。
  • Componentが状態を持ち、データを更新するためにStateが存在します。

(例) Headerの中のLoginBtnと親子関係になっています。

Header.jsx
class Header extends Component {
  render() {
    return (
      <div>
        <LoginBtn />
      </div>
    );
  }
}

例) 状態を利用して、出力内容を分岐する

LoginBtn.jsx
class LoginBtn extends Component {
  constructor() {
    super();
    this.state = { loggedIn: false }
  }

  render() {
    const message = this.state.loggedIn ? "ログアウト" : "ログイン";

    return (
      <div>{ message }</div>
    );
  }
}

それぞれの特徴を一言で述べるなら、
Stateは「Componentが持っている状態」の事を、
Propsは「 親Componentから渡された値」を指します。

Propsについて

  • Props は親Componentから子Componentに渡される値です。
  • Props は不変のデータとして扱われます。
  • 親Componentから渡された値か、defaultPropsメソッドを使う事で、コンポーネント側でデフォルトの値を設定することも可能です。
App.jsx
App.defaultProps = {
    firstProp: 'Hello, World!',
    secondProp:  ' Welcome to React'
}

render内のdivの{ this.props.firstProp }{ this.props.secondProp }は、App.defaultProps内で定義されています。

propsの値は{}でくくる事でComponentのレンダリング処理中に評価され、値を出力することが出来ます。

App.jsx
return (
    <div>
        { this.props.firstProp }
        { this.props.secondProp }
    </div>
);  //出力結果: Hello, World! Welcome to React

Propsの例 ) 親から子への値の受け渡し

App.jsx
import React, {Component} from 'react';

class Title extends React.Component {
  render() {
    return (
      <h1 className="hello"> {this.props.value} </h1>
    );
  }
}

class Text extends React.Component {
  renderTitle(i) {
    return <Title value={i} />;
  }

  render() {
    return (
        <div className="text"> {this.renderTitle('hello')} </div>
    );

  }
}

export default Text;

解説
1. 親要素class Textのrender内の{this.renderTitle('hello')}がclass Text内のrenderTitleメソッドを呼び出しています。
2. メソッドrenderTitle(i)は、受け取った引数をclass Titleのvalueに代入します。
3. 子要素class Title内の<h1 className="hello"> {this.props.value} </h1>renderTitle(i)メソッドで代入された値を出力します。

React Developer Toolsをインストール済みの場合、Google ChromeのDeveloper Toolsを起動してReactタブを確認すると、解説通りのツリー構造になっているのが確認出来ます。

Screen Shot 2017-10-10 at 17.37.34.png (107.6 kB)

Stateについて

  • StateはComponentの状態を表します。State は可変のデータで変更可能です。

  • 継承を使用する場合、this.setState()をComponent内で呼び出すことによってStateの値を更新することが出来ます。

  • 継承を使用する場合、Component間でStateを直接共有することは出来ません。

  • 継承を使用する場合、Stateの値はクラス定義の際にcostructorを呼び出して初期化します。初期値は連想配列を使って渡します。

Stateの例 ) Counterアプリ

  • 以下の例ではaddが実行される度にthis.setStateで値が更新されます。
App.jsx
class App extends Component {
  constructor() {
    super();
    this.state = { count: 0 }
  }

  add() { this.setState({ count: this.state.count + 1 }); }

  render() {
    return (
      <div>
        <button onClick={ () => this.add() }>count</button>
        <h1>{ this.state.count }</h1>
      </div>
    );
  }
}

おわりに

StateとPropsの特徴と使い方を覚える事ができました。
補足、間違っている箇所がございましたらご指摘よろしくお願いします。

株式会社VRizeは、VR広告ネットワークやVR動画アプリの制作等、VRに関わる様々なサービスを製作しています。VRとReactに興味があるフロントエンジニアさん、絶賛募集中です!
https://vrize.io/recruits/
https://www.wantedly.com/projects/79383