React 初心者向け 完全ガイド [翻訳記事]
Tags: react, javascript, webdev, tutorial
Published: 2018-09-08 03:55:37

---
title: React 初心者向け 完全ガイド [翻訳記事]
published: true
description: React 初心者向け 完全ガイドです。React の開発もとである Facebook のコンポーネントを例にとったチュートリアルがメインです。ソースコードを多数掲載しながら、段階的に実装と機能が追加されていくさまをわかりやすく表しています。
tags: React, JavaScript, Web Development, Tutorial
cover_image: https://zen-of-programming.com/react-intro/PostHeader.jpg
---

本記事は、以下の記事の翻訳です:
[A Complete Beginner's Guide to React](https://zen-of-programming.com/beginners-guide-react/) by [Ali Spittel](https://zen-of-programming.com/) on [The Zen of Programming](https://zen-of-programming.com/)
<small>* 執筆者に許諾を頂いた上で掲載しています。</small>

---

もっとたくさんのコードで動くものを書いてみたいと改めて考えています。
そして React は私の大好きな技術の一つです。
そこで React の入門編をつくろうと考えました！
本記事は HTML と JavaScript の知識があることを前提にしています――これらは React のようなライブラリを導入する前に身に着けておくべきである、というのが私の強い持論です。


## React とは

React は JavaScript のライブラリです。
2013 年に Facebook の開発チームによってつくられました。ユーザーインタフェースをよりモジュラーに（あるいは再利用可能に）して、メンテナンスをより容易にすることを、目的としています。
React の Web サイトによると「自分自身の state（状態）を管理するカプセル化されたコンポーネントを構築して、それらをもとに複雑な UI を構成する」ために使われています。

私は本記事の中で Facebook を例にしたサンプルを多く使います。
なぜなら彼らがまず最初に React を書いたからです。

Facebook で、ただイイねを付けるだけの仕様から、複数のリアクションが取れるようになった時のことを、覚えていますか？
投稿に対して、ただイイねを付けられるだけだったそれまでと変わって、ハートやスマイリーのようなものを、どの投稿に対しても付けられるようになったのです。
もしそれらのリアクションを HTML 主体で作成していたとしたら、すべてのイイねをリアクションに変更して、それらがきちんと動くことを確認するために、とんでもない労力が必要になっていたことでしょう。

これが React が登場した契機です――最初に「関心の分離」を実装して、それを開発者を押し付けるやり方ではありません。異なるプログラミング言語を分離する代わりに、React 内に異なるアーキテクチャを持つのです。そしてコンポーネント構造に基づく形でモジュール性を高めるのです。

> 今回は、CSS は別の扱いにしています。しかし、もしお望みでしたら CSS をコンポーネント特有のものにすることもできます！

### React vs. Vanilla JavaScript

「Vanilla（ヴァニラな）」JavaScript について話す時、jQuery / React / Angular / Vue のようなライブラリを追加していない JavaScript コードを書くことについて話すのが、一般的です。
もしそれらがどのようなものであるのかについて、あるいはフレームワークとはどういうものであるのかについて、より詳しく知りたいとお考えでしたら、 [Web フレームワーク全般についての記事](https://zen-of-programming.com/web-framework-intro/) も書いています！



## 始める前のいくつかの注意点

- このチュートリアルを少しでも簡潔なものにするために、コードサンプルの前後に `...` を付けることがあります。これはコードの一部を省略しているという意味です。
- Git diff を使用して、コードのどの行を変更したかを表している箇所があります。その箇所をコピー & ペーストする時には、行の先頭の `+` を削除してください。
- どの節でもコード全体の完全なバージョンを CodePen で公開しています――実際に動かすこともできます！
- 本チュートリアルに必須では無い、より高度な概念がある場合は、引用形式でそれを示しました。多くは純然とした事実ですが、おもしろい内容だと思います。


## 準備

React アプリケーションの製品を作成するにあたっては、ビルドツールを使いたくなるでしょう。
たとえば Webpack のようなものです。
React は、ブラウザ上で、デフォルトでは動かないいくつかのパターンを利用しています。
ビルドツールは、そのようなものをとりまとめてくれます。
[Create React App](https://github.com/facebook/create-react-app) は、この種の目的のために、非常に役立ちます！
ほとんどの設定を終えてくれているのです！

それでは今からですが、てきぱきと進めて React のコードを実際に書いて行きたいですね。
そこで、開発のみの用途で配布されている React の CDN を、利用しましょう！
Babel の CDN も利用しましょう。非標準の JavaScript の機能もいくつか利用できるようになります。（そのことについては、のちほどさらに触れて行きます！）

```html
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/6.1.19/browser.js"></script>
```

[Codepen のテンプレート](https://codepen.io/aspittel/pen/gdrexE) も作成して使えるようにしています！

本格的な React プロジェクトでは、私はコンポーネントを複数のファイルに分割するようにしています。
しかし、繰り返しになりますが、今回は学習が目的です。
そこで JavaScript を 1 つのファイルにまとめます。


## コンポーネント

このチュートリアルでは、Facebook の近況報告ウィジェットを作成します。
なぜなら Facebook が React を最初に書いたからです！

Facebook 上には、いくつの `like` （イイね）ウィジェットが現れる箇所があるでしょうか――近況報告に対してイイねと言うこともあるでしょうし、あるいはそれに紐付く投稿や、動画の投稿、あるいは写真に対してということもあるでしょう！ もしくは、ページそのものに対して、ということさえあり得ますね！
イイね機能にまつわる何かを調節する時に、常にそれらすべての箇所に変更を加えなくてはならない、という事態を、Facebook は望んでいません。
だからこそコンポーネントの出番になるわけです！
Web ページ上の再利用可能な部品のすべてが、抽象化されてコンポーネントになります。
そして、何度も何度も繰り返し使うことができるようになります。
私たちがそれをアップデートするには、一箇所のコードを変更するだけで十分になるのです。

それでは Facebook の近況報告のイメージを見て、その中でどのようなコンポーネントが組み合わされているのかを、見て行きましょう。

![](https://zen-of-programming.com/react-intro/facebook-status.png)

近況報告それ自体が、一つのコンポーネントになるでしょう――Facebook のタイムラインにはたくさんの近況報告があります。
そのため、きっと、近況報告コンポーネントを再利用できるようにしたくなるはずです。

そのコンポーネントの中では、サブコンポーネントやコンポーネントが、親コンポーネントの中に存在しているでしょう。
それらは同様に再利用可能であるでしょう――だからこそイイねボタンコンポーネントは、`PhotoStatus` コンポーネントや `LinkStatus` コンポーネントの子になり得るのです。

サブコンポーネント群はこのように見えるかもしれません:

![](https://zen-of-programming.com/react-intro/components.png)

サブコンポーネントの中にサブコンポーネントを持つことさえできます！
それがために、イイね（Like） / コメント（Comment） / シェア（Share）の集合体が、それ自体として `ActionBar` コンポーネントになり、その中でイイね / コメント / シェアの処理を行う、ということができるのです。

![](https://zen-of-programming.com/react-intro/subcomponents.png)

アプリケーションのどこでその機能を再利用するかということを鑑みながら、これらのコンポーネントやサブコンポーネントを整理するのに役立つであろう方法は、たくさんあります。


## 始めましょう

このチュートリアルを始めるにあたってまず React の「Hello World」を行いましょう――結局のところ、これが伝統的なやり方です！
それから少し複雑な近況報告のサンプルに進みましょう。

HTML ファイルに、一つだけ要素を追加しましょう――id 付きの `div` です。
ごく自然な形で div が id を持っているように見えますね。
これが、私たちの React アプリケーションの root （出発点）です！

```html
<div id="root"></div>
```

もし CodePen のテンプレートを使ってコードを書いているのでしたら、この JavaScript を直接 `js` セクションに記述して頂いて結構です。
もし、そうでは無く、ご自身のコンピューターでこのコードを書いているのでしたら、`text/jsx` 指定付きで script タグを追加する必要があります。このような感じです:

```html
<script type="text/jsx"></script>
```

さあ、React のコードに触れてみましょう！

```javascript
class HelloWorld extends React.Component {
  render() {
    // React に対して、どのような HTML コードをレンダリングするのかを伝える
    return <h1>Hello World</h1>
  }
}

// React に対して、HelloWorld コンポーネントを HTML の 'root' div にアタッチするように伝える
ReactDOM.render(<HelloWorld />, document.getElementById("root"))
```

何が起こるでしょうか。
ただページに「Hello World」が H1 として表示されるだけです！

ここからどのように進めて行くのかについてお話しましょう。

まず、ES6 のクラスを使い、`React.Component` クラスを継承します。
これは React コンポーネントの大部分で使用することになるパターンです。

次に、クラスの中に一つのメソッドを作成します―― `render` と呼ばれる特殊なメソッドです。
React は `render` メソッドを探します。このメソッドがページに何をレンダリングするかを決定するのです！
この名前はわかりやすいですね。
`render` メソッドが返すものは、それが何であれ、そのコンポーネントによってレンダリングされるのです。

今回の場合、「Hello World」というテキスト付きの H1 が返されています――これは確かに HTML ファイルにおいて至極まっとうな内容です。

最後に、このように書きましょう:

```javascript
ReactDOM.render(<HelloWorld />, document.getElementById("root"))
```

ReactDOM の機能を使って、react コンポーネントを DOM にアタッチするのです。

> React は仮想 DOM と呼ばれるものを利用します。これは、通例では Vanilla JavaScript や jQuery によって操作する DOM の、仮想的な表現です。 `reactDOM.render` によって仮想 DOM から実 DOM にレンダリングされます。インタフェース上の何かで変更が必要になった時に、DOM の効果的な編集と再レンダリングを行うために、React は舞台裏でたくさんの仕事を行っているのです。

私たちのコンポーネント `<HelloWorld />` は HTML タグのように見えますね！
この構文は、JavaScript の拡張である *JSX* の一部です。ブラウザ上でネイティヴには使用できません。
Babel によって JavaScript を処理していることを覚えていますか？
Babel が JSX を通常の JavaScript にトランスパイル（あるいは変換）することで、ブラウザが理解できるようにしているのです。

> JSX は実際には React を使う上での選択肢の一つです。しかし大多数のケースで目にすることになるでしょう！

その後では JavaScript のビルトインである `document.getElementById` を使用して root 要素を取得し、HTML を生成しています。

おおまかに言うと、この `ReactDOM.render` 文において、 `HelloWorld` コンポーネントが HTML ファイルに定義された `div` にアタッチされます。


## スターターコード

さあ、それでは――これで「Hello World」は終わりです。
Facebook コンポーネントに進んで行きましょう。

まず、このデモを触って見てください。
このチュートリアルの残りで、こちらの内容に取り組んで行きます。
気軽にコードも見てみてください。
理解できなくても心配ありません！ このチュートリアルの残りで説明する内容です！

{% codepen https://codepen.io/aspittel/pen/rZLaeJ %}

HTML にウィジェットを「ハードコーディング」することから始めましょう:

```html
<div class="content">
  <div class="col-6 offset-3">
    <div class="card">
      <div class="card-block">
        <div class="row">
          <div class="col-2">
            <img src="https://zen-of-programming.com/react-intro/selfiesquare.jpg" class="profile-pic">
          </div>
          <div class="col-10 profile-row">
            <div class="row">
              <a href="#">The Zen of Programming</a>
            </div>
            <div class="row">
              <small class="post-time">10 分前（10 mins）</small>
            </div>
          </div>
        </div>
        <p>Hello World!</p>
        <div>
          <span class="fa-stack fa-sm">
            <i class="fa fa-circle fa-stack-2x blue-icon"></i>
            <i class="fa fa-thumbs-up fa-stack-1x fa-inverse"></i>
          </span>
        </div>
        <div>
          <hr class="remove-margin">
          <div>
            <button type="button" class="btn no-outline btn-secondary">
              <i class="fa fa-thumbs-o-up fa-4 align-middle" aria-hidden="true"></i>
              &nbsp;
              <span class="align-middle">イイね（Like）</span>
            </button>
          </div>
        </div>
      </div>
      <div class="card-footer text-muted">
        <textarea class="form-control" placeholder="コメントはこちらへどうぞ...（Write a comment...）"></textarea>
        <small>残り 120 字（120 Remaining）</small>
      </div>
    </div>
  </div>
</div>
```

CSS をいくつか追加すると、次のような見た目になります:

![](https://zen-of-programming.com/react-intro/status-component.png)

[CodePen に作成したスターターコードがこちらにあります。](https://codepen.io/aspittel/pen/KxzGdx)

このチュートリアルの目的のために、4 つのコンポーネントを生成しましょう:
まずは、親になる `Status` コンポーネント / イイね機能のロジックを有する `Like` コンポーネント / コメントをタイプするためのロジックを持つ `Comment` コンポーネントです。
さらに、 `Like` コンポーネントに `LikeIcon` という子を持たせます。イイねボタンの切換えを行う時に表示したり非表示にしたりするものです。

## コンポーネントのアーキテクチャ

さらに進めて行きましょう。
コンポーネントに書き込んだ HTML コードを分割して行きます。

コンポーネントの骨組みから始めましょう。
同じようにレンダリングされて、きちんと動くはずです！

```html
class Status extends React.Component {
  render() {
    return (
      <div className="col-6 offset-3">
        <div className="card">
          <div className="card-block">
            <div className="row">
              <div className="col-10 profile-row">
                <div className="row">
                  <a href="#">The Zen of Programming</a>
                </div>
                <div class="row">
                  <small className="post-time">10 分前</small>
                </div>
              </div>
            </div>
          </div>
          <p>Hello world!</p>
          <div className="card-footer text-muted" />
        </div>
      </div>
    )
  }
}

ReactDOM.render(<Status />, document.getElementById("root"))
```

> 上記に関して、おもしろい注釈があります。私たちは「class」属性を「className」に変更しなければなりませんでした。クラスは、JavaScript において標準で意味を持つものです――ES6 のクラス機能のことです！ JSX の表現上、属性の中には HTML と違う名前になっているものもあるのです。

HTML 内の content は削除しても大丈夫です。ID が root である要素を残しておけば十分です――親の「content」という div は、スタイルのためだけに定義しています！

```html
<body>
  <div class="content">
    <div id="root"></div>
  </div>
</body>
```

これが Status コンポーネントに変わる HTML です。
もとになる HTML の一部はまだ現れていないことに、留意しておいてください――サブコンポーネントになる部分です！

二番目のコンポーネントをつくって行きましょう。
そしてそれを `Status` コンポーネントに組み入れてあげましょう。

```javascript
class Comment extends React.Component {
  render() {
    return (
      <div>
        <textarea className="form-control" placeholder="コメントはこちらへどうぞ..." />
        <small>残り 140 字</small>
      </div>
    )
  }
}
```

これはコメントのためのコンポーネントです。
入力可能な `textarea` と残り入力可能な字数を表すテキストのみが存在します。
いずれもが 1 つの `div` でラップされていることに気を付けてください――これは React の仕様です。すべてのコンポーネントを 1 つの HTML タグでラップする必要があります――親の `div` を定義しなかった場合 `textarea` と `small` タグは取得できません。

それでは、このコンポーネントを `Status` コンポーネントに組み入れて行きましょう。サブコンポーネントにする、というわけです。
Status コンポーネントをレンダリングするために使用したのと同じ JSX の構文を使用して、実現できます！

```javascript
class Status extends React.Component {
  render() {
    return (
      <div className="col-6 offset-3">
        <div className="card">
          <div className="card-block">
            <div className="row">
              <div className="col-10 profile-row">
                <div className="row">
                  <a href="#">The Zen of Programming</a>
                </div>
                <div className="row">
                  <small className="post-time">10 分前</small>
                </div>
              </div>
            </div>
          </div>
          <div className="card-footer text-muted">
+           <Comment />
          </div>
        </div>
      </div>
    )
  }
}
```

よろしいでしょうか。
さあ、イイねについても全く同じことをする必要があります！

```javascript
class LikeIcon extends React.Component {
  render() {
    return (
      <div>
        <span className="fa-stack fa-sm">
          <i className="fa fa-circle fa-stack-2x blue-icon" />
          <i className="fa fa-thumbs-up fa-stack-1x fa-inverse" />
        </span>
      </div>
    )
  }
}

class Like extends React.Component {
  render() {
    return (
      <div>
        {/* Like コンポーネントの中に LikeIcon サブコンポーネントを含める */}
        <LikeIcon />
        <hr />
        <div>
          <button type="button">
            <i
              className="fa fa-thumbs-o-up fa-4 align-middle"
              aria-hidden="true"
            />
            &nbsp;
            <span className="align-middle">イイね</span>
          </button>
        </div>
      </div>
    )
  }
}
```

次は、もとの `Status` コンポーネントに、それを組み込む番です！

```javascript
class Status extends React.Component {
  render() {
    return (
      <div className="col-6 offset-3">
        <div className="card">
          <div className="card-block">
            <div className="row">
              <div className="col-10 profile-row">
                <div className="row">
                  <a href="#">The Zen of Programming</a>
                </div>
                <div className="row">
                  <small className="post-time">10 分前</small>
                </div>
              </div>
            </div>
+           <Like />
          </div>
          <div className="card-footer text-muted">
            <Comment />
          </div>
        </div>
      </div>
    )
  }
}
```

良いですね。
さあ、もとの HTML を React 化できました。
しかしまだ何も動かないですね！
対応して行きましょう！

概観すると、この節で出てきたコードは [この CodePen](https://codepen.io/aspittel/pen/yxOQMe?editors=0010) のような感じです！

## State（状態）と Props（属性）

私たちが実装したいのは、ユーザーとの二種類のやり取りです。

- イイねボタンが押された時だけ、イイねアイコンを表示する
- 入力に応じて、残り文字数を減少させる

これらのことに取り組んでいきましょう！

### Props（属性）

想像してみてください。
コメントボックスを複数の場所に設置してそれぞれに対して文字数制限を設定しようとしたらどうでしょうか。
例えば、近況投稿においては、ユーザーが 200 文字まで返信を書けるようにしましょう。
ところが、写真投稿においては、100 文字までしか返信を書けないようにするのです。

React では `PictureStatus` コンポーネントから props（properties の略です）を受け取ることができます。
そして `Status` コンポーネント側で返信を何字制限にするのかを指定できます。
二種類のコメントコンポーネントをつくる必要はありません。

props の構文は次のような感じです:

```javascript
<Comment maxLetters={20} />
<Comment text='hello world' />
<Comment show={false} />

var test = 'hello world'
<Comment text={test} />
```

この props は HTML の属性のように見えますね！
props を介して文字列を渡す場合は、括弧は要りません。
しかし他のデータ型や変数を渡す場合は、括弧の中に書く必要があります！

これで、コンポーネントの中で、props を使えるようになりました:

```javascript
console.log(this.props.maxLetters)
```

データはインスタンスの `props` 属性の中に集約されています。
そのため `this.props.myPropName` でアクセスできます。

それでは、ハードコーディングしていた 140 字を、コンポーネントの外から変更しやすいように、つくり変えてあげましょう！

まず、Status コンポーネントの中で Comment コンポーネントのインスタンスを生成している箇所を変更します（ただしコードの一部は省略しています！）:

```javascript
class Status extends React.Component {
        ...
          <div className="card-footer text-muted">
+            <Comment maxLetters={280} />
          </div>
        </div>
      </div>
    )
  }
}
```

次に、Comment コンポーネントにハードコーディングしていた 140 字制限を変更します。

```javascript
class Comment extends React.Component {
  ...
        <div>
        <textarea className="form-control" placeholder="コメントはこちらへどうぞ..." />
+       <small>残り {this.props.maxLetters} 字</small>
      </div>
  ...
}
```

### State（状態）

コンポーネントからコンポーネントへ渡す props は *決して* 子コンポーネントの中では変更されません――親においてのみ変更され得るのです。子においてはあり得ません。
しかし――あるコンポーネントの処理中に変更したいと思う属性が出てくることは少なからずあるでしょう。
例えば、ユーザーが textarea に入力済の文字数の合計を保持しておいたり、近況報告が「イイね」されているのか否かを保持しておいたり、などです。
変更したいそれらの属性は、コンポーネント中の *state* に格納します。

> React にはたくさんの不変性が存在することに気付くでしょう――関数型パラダイムに強く影響を受けているためです。同様の理由から副作用も避けるべきとされています。

この state は、コンポーネントの新しいインスタンスを生成した時はいつでも、使えるようにしておきたいものです。
そこで ES6 のクラスコンストラクタを使って生成するようにしてあげましょう。
ES6 のクラスをさっと復習したい場合には [MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Classes) がすばらしい教材になります！

state はあらゆる key-value ペアから構成されるオブジェクトです。
今回必要なのは、ユーザーが入力済である文字数を格納する characterCount です。
さしあたっては 0 をセットしておきましょう！

```javascript
class Comment extends React.Component {
  constructor () {
    super()
    this.state = {
      characterCount: 0
    }
  }
  ...
```

さあ `maxLetters` 属性の減算処理を行いましょう。
それによって残り字数が常に把握できるようになります！

```html
<small>残り {this.props.maxLetters - this.state.characterCount} 字</small>
```

`characterCount` が増加すると、残り字数の表示が減少するでしょう！

おや――入力しても何も起こりませんね！
`characterCount` の値を変更することが全くできていません。
`textarea` に対してイベントハンドラを追加する必要があるのです。
そうすれば、ユーザーが入力を行った時に、`characterCount` を変化させることができます。

### イベントハンドラ

これまでに JavaScript を書いたことがあるのなら、おそらくイベントハンドラを書いてユーザー入力を処理したことがあるでしょう。
React で同じことをして行きましょう。
構文はほんの少しだけ異なります。

`onChange` ハンドラを `textarea` に追加します。
その中で、イベンドハンドリングを行うメソッドへの紐付けを行います。
ユーザーが `textarea` に入力を行うと常にそのメソッドが実行されるようになります。

```html
  <textarea className="form-control" placeholder="コメントはこちらへどうぞ..." onChange={this.handleChange}/>
```

次は `handleChange` メソッドを作成する番です！

```javascript
class Comment extends React.Component {
  constructor () {
    super()
    this.state = {
      characterCount: 0
    }
  }
  
  handleChange (event) {
    console.log(event.target.value)
  }
...
```

ここでは `event.target.value` を `console.log` しているだけです――これは React が無い時に JavaScript で行うのと同じように動くでしょう。（もっとも、少し深く調べてみると、イベントオブジェクトがほんの少しだけ違うことがわかります。）
コンソールを見ると、テキストボックスに入力している内容が出力されていますね！

さて state の中の `characterCount` 属性を更新する必要があります。
React においては、 *決して直接は state を書き換えません* 。
そういうわけで、このようなことはしてはいけません:
`this.state.characterCount = event.target.value.length` 。
代わりに `this.setState` メソッドを使用します。

```javascript
  handleChange (event) {
    this.setState({
      characterCount: event.target.value.length
    })
  }
```

おや！ エラーが発生します――「Uncaught TypeError: this.setState is not a function（捕捉されなかった型エラー: this.setState は関数ではありません）」。
このエラーは、イベントハンドラ内では ES6 のクラスのコンテキストを保護する必要がある、ということを訴えています。
`this` をコンストラクタのメソッドにバインドすることで、このエラーは回避できます！
もしこのことについてさらに読み物が欲しければ [こちらによい記事があります](https://medium.freecodecamp.org/this-is-why-we-need-to-bind-event-handlers-in-class-components-in-react-f7ea1a6f93eb) ！

```javascript
class Comment extends React.Component {
  constructor () {
    super()    
    this.handleChange = this.handleChange.bind(this)
...
```

やりましたね！ ゴールはすぐそこです！
あと必要なのは `like` の表示を切り替える機能を追加するだけです。

`Like` コンポーネントにコンストラクタを追加しましょう。
そのコンストラクタにおいて、コンポーネントの state インスタンスを生成します。
コンポーネントのライフサイクルの中で、その近況報告がイイねされたのか否かということが、変わって行きます。

```javascript
class Like extends React.Component {
  constructor() {
    super()
    
    this.state = {
      liked: false
    }
  }
  ...
```

それから、イベントハンドラを追加して、その近況報告に対して、イイねを付けたり外したりということをしなくてはなりませんね！

```javascript
class Like extends React.Component {
  constructor() {
    super()
    
    this.state = {
      liked: false
    }
    
    this.toggleLike = this.toggleLike.bind(this)
  }
  
  toggleLike () {
    this.setState(previousState => ({
      liked: !previousState.liked
    }))
  }
...
```

これまでと違うことがあります。 `this.setState` が持つコールバック関数がパラメーターを受け取っています―― `previousState` です。
パラメーターの名前から推測できるかもしれませんが、これは `this.setState` がコールされる前の state の値です。
`setState` は非同期処理です。そのために `this.state.liked` は信頼できないのです。

必要なことが出揃いましたね:

a) ユーザーがイイねボタンをクリックすると常に、イベントハンドラをコールする
b) `liked` が true である場合にのみ、LikeIcon を表示する

```javascript
  render() {
    return (
      <div>
        {/* boolean で制御して、liked が true である場合にのみ LikeIcon をレンダリングする */}
+       {this.state.liked && <LikeIcon />}
        <hr />
        <div>
+          <button type="button" className="btn no-outline btn-secondary" onClick={this.toggleLike}>
            <i
              className="fa fa-thumbs-o-up fa-4 align-middle"
              aria-hidden="true"
            />
            &nbsp;
            <span className="align-middle">イイね</span>
          </button>
        </div>
      </div>
    )
  }
```

すばらしいです！
私たちの機能が完成しました！

## おまけ: 関数型コンポーネント

もし既におなかいっぱいだよということでしたら、この部分は飛ばしてください。
しかし私としては、今回のプロジェクトにさっと一つだけリファクタリングを加えたいと思いました。
もし紐付く state が存在しないコンポーネントをつくったならば（ステートレスなコンポーネントと呼ばれるものです）、コンポーネントは ES6 のクラスでは無く関数として扱うことができるようになります。

そのようにした場合、 `LikeIcon` はこのようなものになるでしょう:

```javascript
const LikeIcon = () => {
  return (
    <div>
      <span className="fa-stack fa-sm">
        <i className="fa fa-circle fa-stack-2x blue-icon" />
        <i className="fa fa-thumbs-up fa-stack-1x fa-inverse" />
      </span>
    </div>
  )
}
```

`render` メソッドは使わずに、コンポーネントの UI を return しているだけです！

[ここに](https://codepen.io/aspittel/pen/NLrPWN) 上記のリファクタリングを実装した CodePen のコードがあります。

## チートシート

私はチートシートが好きです。
そこで今回の投稿をもとにした内容で、一つ、つくってみました！

![](https://zen-of-programming.com/react-intro/cheatsheet.png)

[ここから](https://zen-of-programming.com/react-intro/cheatsheet.pdf) PDF としてダウンロードすることもできます！

## 次のステップ

振り返りをしましょう。
私たちは次のことについてお話しました。
コンポーネントのアーキテクチャ / 基本的な React の構文と JSX / state（状態） と props（属性） / イベントハンドラ / 関数型コンポーネント、についてです。

このチュートリアルに基づく CodePen のコードはすべて [ここに](https://codepen.io/collection/XpPbVv/) 揃えています！

もしこのチュートリアルのコードを拡張してみたいとお考えでしたら、イイね機能をリアクション機能に変更してみたり、写真コンポーネントを作成してみたりして、既につくったコンポーネントのいくつかを再利用してみると良いかもしれません！

React を学習するにあたっては、他にも、次のようなすばらしいコンテンツがあります:

- [React Documentation](https://facebook.github.io/react/tutorial/tutorial.html)
- [DevCoffee](https://www.youtube.com/watch?v=ZnRFerIP8aA)
- [Wes Bos Redux](https://www.youtube.com/watch?v=hmwBow1PUuo&list=PLu8EoSxDXHP5uyzEWxdlr9WQTJJIzr6jy)

## 引き続きよろしくお願いします

もし本記事に対してイイねと感じて、もっと読みたいと思って頂けたのでしたら、お伝えしたいことがあります。
私は [週刊のニュースレター](https://tinyletter.com/ali_writes_code) を発行していて、その週の中で良いと感じたもののリンクや私が書いた最新の記事についての情報をお送りしています。
さらに、 チュートリアルとして私に書いて欲しいと思う内容や、これらのことをより簡単に理解できるようにするための建設的なフィードバックがあれば、私へ [ツイート](https://twitter.com/aspittel) してください！
何か疑問点がある場合は、私の [AMA repo](https://github.com/aspittel/ama) までご連絡頂けましたら幸いです！

---

お読み頂きどうもありがとうございました。

本記事は、以下の記事の翻訳です:
[A Complete Beginner's Guide to React](https://zen-of-programming.com/beginners-guide-react/) by [Ali Spittel](https://zen-of-programming.com/) on [The Zen of Programming](https://zen-of-programming.com/)

To Ali: Thank you so much for your kind permission for me to translate your post.