もがき系プログラマの日常

もがき系エンジニアの勉強したこと、日常のこと、気になっている技術、備忘録などを紹介するブログです。

React入門を読み始めた(パート2)

はじめに

こんばんは。

今日は前回の続きをいつもと同じく社内のデザイナーさん(@chups_coke)と、React入門の本を読み進めました。

だいぶ時間空いたのは、僕もデザイナーさんも体調崩していたからなのです・・・。

React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで (NEXT ONE)

React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで (NEXT ONE)

やってみた

目次

今回読み進めたのは以下。

  1. Reactコンポーネント
  2. stateとイベントハンドリング

Reactコンポーネント

Reactのコンポーネントの種類は大きく分けて2種類が存在しているとのこと。

  • Functional Component
  • Class Component

関数定義のコンポーネントとクラス定義のコンポーネントということ。

Functional ComponentとClass Componentの違い

違いは定義の違いだけではなく、ClassComponentには、コンポーネントの状態を記録管理する state という概念が存在している。

また、ClassComponentには、ライフサイクルメソッドという独自メソッドも存在しているらしい。

iosとかのviewDidLoadとかとおんなじ感じかな??

Reactエレメント

他の言語でいうインスタンスとのこと。

# これはReactコンポーネント
const Test = () => {
  return (
    <div>あああ</div>
  );
};

ReactDOM.render(
  <div>
    # これはReactエレメント
    <Test />
  </div>,
  document.getElementById('root')
);

Flagmentコンポーネント

Reactコンポーネントは単一の親からなる要素しか返せないとのこと。

以下の書き方は「単一の親ではない」のでNG

const Test = () => {
  return (
    <div>あああ</div>
    <div>いいい</div>
  );
};

以下の書き方は、「単一の親」なのでOK

const Test = () => {
  return (
    <div>
      <div>あああ</div>
      <div>いいい</div>
    </div>
  );
};

とりあえず上記で通るけど、これだと出力されるHTMLに本来いらないHTMLタグが追加されてしまう。

こういうときにFlagmentコンポーネントが使えるみたい。

const Test = () => {
  return (
    <React.Fragment>
      <div>あああ</div>
      <div>いいい</div>
    </React.Fragment>
  );
};

一番上でくくっている <React.Fragment> は出力時にはHTMLとして処理されないので、最終的に出力されるHTMLは、以下のようになる。

<div>あああ</div>
<div>いいい</div>

<React.Fragment><></> みたいな感じで省略記法を使うことが出来るみたいだけど、個人的に圧倒的に可読性落ちちゃうので、使わないと思う。。。

データの受け渡し(props)

要は引数を渡せるということ。

const Test = (props) => {
  return (
    <div>{props.name}</div>
  );
};

ReactDOM.render(
  <div>
    <Test name="あああ" />
  </div>,
  document.getElementById('root')
);

propsという名前は、なんでもいいけどpropsとつけるのが一般的とのこと。

object型なので、今回は nameを渡してるけど、 当然他にもいろいろと渡せる。

渡せる値は、文字列でも数字でも関数でもオブジェクトでも基本的に何でも渡せるっぽい。

例外あるのかな?

children

コンポーネントを組み合わせて(繋ぎ合わせて)使うReactでは、これが結構重要な感じがした。

propsの特別なプロパティとして、childrenは存在しているみたい。

Reactコンポーネントの小要素が入ってくる

const Test = (props) => {
  return (
    <div>テストだよ!{props.children}</div>
  );
};

ReactDOM.render(
  <div>
    <Test>
      テストテスト
    </Test>
  </div>,
  document.getElementById('root')
);

出力されるHTMLは以下

<div>
  <div>テストだよ!テストテスト</div>
</div>

こんな感じで文字列をchildrenに渡すことが出来るが、Reactエレメントを渡すことが出来る。

const Test1 = () => {
  return (
    <div>テストだよ!</div>
  );
};

const Test2 = (props) => {
  return (
    <div>
      <p>今日のテスト</p>
      {props.children}
    </div>
  );
};

ReactDOM.render(
  <Test2>
    <Test1 />
    <Test1 />
    <Test1 />
  </Test2>,
  document.getElementById('root')
);

出力されるHTMLは以下

<div>
  <p>今日のテスト</p>
  <div>テストだよ!</div>
  <div>テストだよ!</div>
  <div>テストだよ!</div>
</div>

多分一番の使い所は、この使い方なのかも。

propTypes

propsに渡す値の型をチェックできる機能のよう。

今回の勉強会では、一緒にやっているデザイナーさんと足並み揃えてやりたかったので、プログラムよりな部分はやらないように、こちらは飛ばした。

stateとイベントハンドリング

stateは最初に書いたとおり、コンポーネントの状態を記憶しておく機能のこと。

本では、簡単なtodoアプリを作りながらの説明だったので、本に沿って実際につくってみた。

f:id:kojirooooocks:20180530042511g:plain

重要なところは、フォームに文字を入力した際にstateを変更させるためのchangeイベントと、登録ボタンを押したときに、todoリストに追加するためのclickイベント。

handleChange(e) {
  this.setState({
    value: e.target.value
  });
}

handleClick() {
  this.props.addTodo(this.state.value);
}

render() {
  return (
    <div>
      <input placeholder="新規TODOを入力してください" onChange={this.handleChange} />
      <button onClick={this.handleClick} >登録</button>
    </div>
  );
}

this.stateはClass Componentの重要なプロパティで、このstateでReactは各コンポーネントの状態を管理しているらしい。

stateの値を変更する場合は、直接修正せずかならず setState() 経由で修正しなければいけない。

終わりに

今回やったtodoアプリはgithubにあげときます。

kojirock/react-sample01

今回はガッツリコンポーネントのことを勉強できたから、勉強した感がありました。

次はライフサイクルのことを勉強するようなので、間を空けずにやっていきたいです。

おやすみなさい。