React公式サイト日本語訳「主な概念」編 　〜公式入門教科書〜


2019.5追記
:flag_jp: https://ja.reactjs.org/ :flag_jp:
↑React公式サイト全体が和訳されました:sunny:　この記事より↑をご覧いただくのが便利です！ 

---
# 前置き
本記事はReact公式ドキュメントの「基礎概念」編の和訳です。長いです。

[React公式ドキュメント](https://reactjs.org/)は、Reactが初めての入門者に対して、以下２つのドキュメントから読者の好みで選んで読み始めるよう促しています。

| 場所 | 「こんな人におすすめ」 | URL |
|:-----------|:------------|:------------|
| Tutorial      |手を動かして学びたい人へ| https://reactjs.org/tutorial/tutorial.html |
| Docs > Main Concepts (主な概念)     | 概念を１つ１つ学びたい人へ      | https://reactjs.org/docs/hello-world.html    から |

Tutorialはコードを真似しながら３目並べゲームを作る内容で、既に多くの和訳記事があります。

この記事で訳したMain Concepts編はかなりの長文であまり訳されていないようですが、
Reactの基礎をやさしく、一歩一歩説明していく素晴らしい教科書になっています。

例えば以下の概念がJavaScriptの基礎だけを前提知識に説明されています。

- JSX
- コンポーネント
- props
- state
- Reactでのイベントハンドリング 

以下はその和訳(第1章ー第8章)です。英文へのリンクを除き、筆者の理解の限りそのままの内容です。
---

# 1.Hello World
最小のReactアプリケーションは、このような見た目をしています。

```JSX
ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('root')
);'
```
**[CodePenで試す](https://reactjs.org/redirect-to-codepen/hello-world)**

“Hello, world!”という見出しがページに表示されます。

上のリンクをクリックし、オンラインのエディターを開いてください。自由に編集して、出力がどのように変わるのかを見てみましょう。このガイドの多くのページには、このような編集可能な例があります。

### このガイドの読み方

このガイドでは、Reactアプリケーションを組み立てる積み木となる、「element（※）」と「コンポーネント」について考えていきます。この２つをマスターすれば、再利用可能な部品から複雜なアプリケーションを作ることができるようになります。

※訳注:React　elementと呼ばれる特別なオブジェクトのこと

> **ポイント**
このガイドは**概念を１つ１つ学んでいきたい**人向けに書かれています。手を動かして学ぶほうが良ければ、[実践的なチュートリアル](https://reactjs.org/tutorial/tutorial.html)をご覧ください。このガイドとチュートリアルはお互いへの補足になるかもしれません。

### 前提知識
ReactはJavascriptのライブラリですから、Javascript言語の基礎的な知識は前提となります。**あまり自信がなければ、[MDNのJavascriptチュートリアル](https://codepen.io/pen?&editors=0010)に挑戦して知識レベルを測る**ことをおすすめします。そうすれば、このガイドで迷子になることもありません。30分〜１時間ほどかかるかもしれませんが、結果的にJavascriptとReactを同時に学ばなくてすみます。

> **注意**
このガイドではあちこちでJavascriptの新しい文法を使っています。ここ数年間Javascriptを使っていなくても、[この３点](https://gist.github.com/gaearon/683e676101005de0add59e8bb345340c)が判れば大体乗り切れます。

さあ、始めましょう！

# 2.JSXの紹介
*この変数宣言について考えてみてください*

```JSX
const element = <h1>Hello, world!</h1>;
```

この不思議なタグの記法は、文字列でもなければ、HTMLでもありません。

これは「JSX」と呼ばれるもので、Javascriptの拡張文法です。UIの見た目を表現するときには、Reactと一緒にJSXを使うことをおすすめします。テンプレート言語を思わせる見た目ですが、JSXはJavascriptの力を完全に受け継いでいます。

JSXは「React　element」を生成します。そのReact elementをDOMにレンダリングする件は次章で扱うとして、以下ではまずJSXの基本知識を解説します。

### なぜJSX?
レンダリングのロジックは、UIについての他のロジック...―イベント・ハンドリング、時間経過による状態の変化、表示のためのデータ整形―...と本質的に対になるものです。Reactはこの考え方を取り入れています。

Reactは、マークアップとロジックを別々のファイルに書いて人為的に技術の領域を分離することは**しません**。
代わりにReactは、その両方を持つ「コンポーネント」という単位で[関心を分離](https://ja.wikipedia.org/wiki/%E9%96%A2%E5%BF%83%E3%81%AE%E5%88%86%E9%9B%A2)します。この先の章でコンポーネントを扱いますが、JSファイルにマークアップを書くことにまだ抵抗があれば、[こちらのプレゼン](https://www.youtube.com/watch?v=x7cQ3mrcKaY)があなたを説得できるかもしれません。

ReactにJSXが必ず必要というわけではありませんが、Javascriptの中でUI作る場合、多くの人はJSXが視覚的に使いやすいと感じます。さらに、JSXを使うとReactのエラーメッセージがより分かりやすくなります。


### JSXに式を入れる

下の例では、`name`変数を宣言し、波括弧`｛｝`で囲んでJSXの中で使っています。

```JSX
const name = 'Josh Perez';
const element = <h1>Hello, {name}</h1>;

ReactDOM.render(
  element,
  document.getElementById('root')
);
```
Javascriptとして有効な式なら何であれ、波括弧で囲んでJSXの中で使えます。例えば`2 + 2`,`user.firstName`,`formatName(user)`はすべて有効なJavascriptの式です。

下の例では、`<h1>`要素にJavascript関数の呼び出し結果`formatName(user)`を埋め込んでいます。

```JSX
function formatName(user) {
  return user.firstName + ' ' + user.lastName;
}

const user = {
  firstName: 'Harper',
  lastName: 'Perez'
};

const element = (
  <h1>
    Hello, {formatName(user)}!
  </h1>
);

ReactDOM.render(
  element,
  document.getElementById('root')
);
```

**[CodePenで試す](https://reactjs.org/redirect-to-codepen/introducing-jsx)**

見やすいようJSXは改行しています。また、文法上必須ではありませんが、「自動セミコロン」の混乱を避けるために常にJSXをカッコ`（）`で囲むのがオススメです。

### JSXも式の一種
コンパイルされた後、JSXは通常のJavasciptの関数呼び出しになり、Javascriptオブジェクトとして評価されます。

そのためJSXは、if文やforループの中に書いたり、変数に入れたり、引数として渡したり、関数から返すことができます。

```JSX
function getGreeting(user) {
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;
  }
  return <h1>Hello, Stranger.</h1>;
}
```

### JSXで属性を指定する
属性に文字列を設定するには、クォートを使えます。

```JSX
const element = <div tabIndex="0"></div>;
```
属性にJavascriptの式を設定するには、波括弧を使えます。

```JSX
const element = <img src={user.avatarUrl}></img>;
```
式を設定する時にクォートはいりません。文字列ならクォート、式なら波括弧と、どちらかを使います。

> **注意**
>JSXはHTMLよりJavaScriptに近いので、ReactDOM（※）はHTML属性名そのままではなく、キャメルケースの命名規則を用います。

>例えば、`class`は`className`に、`tabindex`は`tabIndex`になります。
>※訳注: JSXから（React elementを経由し）DOMを操作してくれるReactの機能

### JSXで子要素を指定する

空要素の場合、XMLのように`/>`ですぐに閉じることができます。

```JSX
const element = <img src={user.avatarUrl} />;
```

JSXのタグは子要素を内包できます。

```JSX
const element = (
  <div>
    <h1>Hello!</h1>
    <h2>Good to see you here.</h2>
  </div>
);
```
### JSXはインジェクション攻撃を防ぐ

JSXには安全にユーザーの入力を埋め込むことができます。

```JSX
const title = response.potentiallyMaliciousInput;
// これも安全:
const element = <h1>{title}</h1>;
```
デフォルトで、ReactDOMはJSXに埋め込まれた全ての変数をレンダリング前にエスケープします。そのため、アプリに明示的に書かれた以外のコードをインジェクトされる心配はありません。レンダリングされる前に全ては文字列に変換されます。この性質はXSS（クロスサイトスクリプティング）の防止に役立ちます。

### JSXはオブジェクトを表現する
BabelはJSXを`React.createElement()`の呼び出しに変換します。

以下２つの例は等価です。

```JSX
const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);
```

```JSX
const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);
```

`React.createElement()`　はバグを防ぐためにいくつかチェック機構を持っていますが、本質的には以下のようなオブジェクトを生成しています。

```JSX
// 注意: これは単純化された構造です
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world!'
  }
};
```

これらのオブジェクトは「React element」と呼ばれています。画面に表示したいモノについての説明文だと思えば良いでしょう。Reactはこれらのオブジェクトを読み込み、DOMを生成・更新するために利用します。

次のセクションでは、React elementsのDOMへのレンダリングについて説明します。

> **ポイント**
お使いのエディタの言語定義は“Babel”にすると、ES6とJSXのコードが正しくシンタックス・ハイライトされるのでオススメです。このサイトはBabelと互換性のあるOceanic Nextというカラースキームを使っています。

# 3.React　elementのレンダリング
*ElementはReactアプリケーションを組み上げる一番小さい積み木です*

１つ１つのelementは、それぞれが画面に表示されたいモノを説明しています。

```JSX
const element = <h1>Hello, world</h1>;
```

ブラウザのDOM要素と違って、React　elementはただのJavaScriptオブジェクトで、軽量に生成できます。あとは、DOMがReact elementの状態通りになるよう、React DOMがDOMを更新してくれます。

> **注意**
elementは、よりよく知られた概念である「コンポーネント」と混同されがちです。次の章でコンポーネントを紹介しますが、elementはコンポーネントを作る部品です。飛ばさずにこの章も読むことをオススメします。

### elementをDOMにレンダリングする
例えばHTMLのどこかに`<div>`があるとしましょう。

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

この要素配下の全要素をReact DOMで管理するという意味で、この要素を「ルート　DOMノード（root DOM node）」と呼びます。

Reactだけで作られたアプリケーションには、通常１つのルートDOMノードがあります。既存のアプリケーションにReactを導入する場合は、何個でも互いに独立したルートDOMノードを作って構いません。

React elementをルートDOMノードの中にレンダリングするには、双方を`ReactDOM.render()`に渡してください。

```JSX
const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));
```

**[CodePenで試す](https://reactjs.org/redirect-to-codepen/rendering-elements/render-an-element)**

ページに“Hello, world”が表示されます。

### レンダリング済みの要素を更新する

React elementはイミュータブル(immutable＝不変)です。後から子要素や属性を変えることはできません。elementは映画の１フレームのようなもので、ある瞬間のUIの状態を表します。

ここまでの知識でUIを更新するには、新しいelementを作ってもう一度`ReactDOM.render()`に渡すしかありません。

以下のチクタク時計のコードを見てください。

```JSX
function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(element, document.getElementById('root'));
}

setInterval(tick, 1000);
```

**[CodePenで試す](https://reactjs.org/redirect-to-codepen/rendering-elements/update-rendered-element)**

`ReactDOM.render()`を`setInterval()`から１秒ごとに呼び出しています。


> **注意**
>実用上は、多くのReactアプリケーションで`ReactDOM.render()`を呼び出すのは一度だけです。以降の章では、「状態を持つコンポーネント(stateful components)」について学んでいきます。
>それぞれの話題はお互いの上に成り立っているので、ぜひ飛ばさずに読んでください。

### Reactは必要なものだけを更新する
React DOMは、

- 現在のelementとその子要素
- 以前のelementとその子要素

を比較し、必要なDOM更新だけを行います。

先ほどのチクタク時計をブラウザのツールで見れば、そのことが確認できます。

![granular-dom-updates-c158617ed7cc0eac8f58330e49e48224.gif](https://qiita-image-store.s3.amazonaws.com/0/233072/3853ef41-1ee1-c4a7-3c9f-62af13adf16b.gif)

UI全体を表すelementを毎秒生成しているにもかかわらず、React DOMが更新しているのは内容が変わったテキストノードだけです。

私達の経験上、「何を変更するか」を考えるよりも「ある瞬間にUIがどう見えるべきか」を考えるほうが、遥かにバグが少なくなります。


# 4.コンポーネントとprops
*コンポーネントを使えば、UIを独立した、再利用可能な部品に分け、それぞれを独立したものとして考えることができます。このページではコンポーネントという概念を紹介します。[詳しいAPIリファレンスはこちら](https://reactjs.org/docs/react-component.html)*

概念的には、コンポーネントはJavaScriptの関数のようなものです。propsと呼ばれる引数を受け付け、画面に表示させるべきものを説明したReact elementを返します。

### functionコンポーネントとClassコンポーネント
コンポーネントを定義する一番単純な方法は、JavaScriptの関数を書くことです。

```JSX
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
```

この関数は、データの入った１つのprops（プロパティの略）オブジェクトを受け取り、React elementを返しているので、有効なReactコンポーネントです。文字通りJavaScriptの関数なので、こうしたコンポーネントを「functionコンポーネント」と呼びます。

また、ES6のClass記法を使ってコンポーネントを定義することも可能です。

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

以上２つのコンポーネントは、Reactからすれば等価です。

Classコンポーネントはいくつか追加の機能を持っていますが、それは次の章で扱います。それまでは簡潔なfuntionコンポーネントを使っていきましょう。

### コンポーネントをレンダリングする

ここまで、私たちはHTMLのタグを表すReact elementだけを扱ってきました。

```JSX
const element = <div />;
```

しかし、elementでユーザーが定義したコンポーネントを表すことも可能です。

```JSX
const element = <Welcome name="Sara" />;
```

Reactがユーザーが定義したコンポーネントを見つけると、JSXに書かれた全属性を１つのオブジェクトとしてコンポーネントに渡します。これを「props」と呼びます。

例えば、以下のコードは “Hello, Sara”とページに表示します。

```JSX
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

const element = <Welcome name="Sara" />;
ReactDOM.render(
  element,
  document.getElementById('root')
);
```

**[CodePenで試す](https://reactjs.org/redirect-to-codepen/components-and-props/rendering-a-component)**


この例で何が起きているのか、おさらいしましょう。

1. このコードは`<Welcome name="Sara" />`elementを渡して`ReactDOM.render()`を呼び出す
2. Reactは`Welcome`コンポーネントに`{name: 'Sara'}`をpropsとして渡して呼び出す
3. `Welcome`コンポーネントは`<h1>Hello, Sara</h1>`element を返す
4. React DOMは返ってきた`<h1>Hello, Sara</h1>`と合致するようDOMを更新する

> **注意:コンポーネント名は常に大文字から始める**
>Reactは小文字から始まるコンポーネントをDOMタグとして扱います。例えば`<div>`はHTMLのdivタグを示しますが、`<Welcome />`はコンポーネントを示し、スコープ内にWelcomeがなければいけません。

### コンポーネントを作る

コンポーネントは出力の中で他のコンポーネントを呼び出すことができます。そのため、様々な詳細度のコンポーネントを抽象化することができます。ボタンも、フォームも、ダイアログも、画面全体も、Reactアプリーケーションではコンポーネントとして表現されます。

例えば、`Welcome`を何度もレンダリングする`App`コンポーネントを作ってみましょう。

```JSX
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

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

**[CodePenで試す](https://reactjs.org/redirect-to-codepen/components-and-props/composing-components)**

新しいReactアプリケーションを作る場合、典型的には最上層に１つの`<App>`コンポーネントを持たせます。既存のアプリケーションに導入する場合、ボタンのような小さなコンポーネントから始め、上層へ上層へとReactの範囲を広げても良いでしょう。

### コンポーネントを分割/抽出する
コンポーネントの分割を恐れないでください。

例えば、この`<Comment>`コンポーネントを考えてみましょう。


```JSX
function Comment(props) {
  return (
    <div className="Comment">
      <div className="UserInfo">
        <img className="Avatar"
          src={props.author.avatarUrl}
          alt={props.author.name}
        />
        <div className="UserInfo-name">
          {props.author.name}
        </div>
      </div>
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}
```

**[CodePenで試す](https://reactjs.org/redirect-to-codepen/components-and-props/extracting-components
)**

propsとして`author`(オブジェクト)、`text`（文字列）、`date`（dateオブジェクト）を受け取り、SNSのコメント欄を表現しています。

ネストが深く、各部分を再利用することも難しいので、扱いづらい状態です。ここからいくつかコンポーネントを抽出してみましょう。

まず、`Avatar`を抽出します。

```JSX
function Avatar(props) {
  return (
    <img className="Avatar"
      src={props.user.avatarUrl}
      alt={props.user.name}
    />
  );
}
```
`Avatar`は自分が`Comment`の中にレンダリングされていることを知る必要はありません。そのため、propsにはより一般的な名前をつけました（author⇨user）。

propsは、コンポーネントを呼び出す時の文脈からではなく、コンポーネント自体の視点から命名することをおすすめします。

これで少しだけ`Comment`をシンプルにできます。

```JSX
function Comment(props) {
  return (
    <div className="Comment">
      <div className="UserInfo">
        <Avatar user={props.author} />
        <div className="UserInfo-name">
          {props.author.name}
        </div>
      </div>
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}
```

次に、ユーザー名の隣に`Avatar`をレンダリングする`UserInfo`コンポーネントを抽出します。

```JSX
function UserInfo(props) {
  return (
    <div className="UserInfo">
      <Avatar user={props.user} />
      <div className="UserInfo-name">
        {props.user.name}
      </div>
    </div>
  );
}
```

これで`Comment`をもう一歩シンプルにできます。

```JSX
function Comment(props) {
  return (
    <div className="Comment">
      <UserInfo user={props.author} />
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}
```

**[CodePenで試す](https://reactjs.org/redirect-to-codepen/components-and-props/extracting-components-continued)**

最初はコンポーネントの抽出を面倒な作業に感じるかもしれません。しかし、大規模なアプリケーションにおいては再利用できるコンポーネントの道具箱を持つことにそれだけの価値があります。経験則として、UIの一部が数回以上使われる（`Button`、`Panel`、`Avatar`...)か、それ単体で十分に複雜（`App`、 `FeedStory`、`Comment`...）な場合、再利用可能なコンポーネントに変える候補になるでしょう。

### propsは読み取り専用
functionコンポーネントにせよClassコンポーネントにせよ、自身のpropsを変更してはいけません。この`Sum`関数を考えてみましょう。

```JSX
function sum(a, b) {
  return a + b;
}
```

このような関数は、入力を変更せず、同じ入力に対してはいつも同じ結果を返すため、「pure」なコンポーネントと呼ばれます。

対照的に、この関数は自分への入力を変更してしまうため「pure」ではありません。

```JSX
function withdraw(account, amount) {
  account.total -= amount;
}
```

Reactはかなり柔軟ですが、１つだけ厳格なルールを持っています。

**全てのReactコンポーネントは、propsに対して「pure」でなければならない**

もちろん、アプリケーションのUIは動的であり、時間とともに変化します。次の章では、「state」(状態)という新しい概念を紹介します。stateの働きで、Reactコンポーネントは上記のルールを破ることなく、ユーザーの行動・ネットワークのレスポンスなど色々な呼び出しに対して、場合によって異なる表示を返すことができます。

# 5.stateとライフサイクル

*この章はReactコンポーネントの「state」と「ライフサイクル」という概念を説明します。[詳しいAPIリファレンスはこちら](https://reactjs.org/docs/react-component.html)* 

過去の章で登場したチクタク時計の例を考えてください。UIを更新する方法は１つだけでした。すなわち、`ReactDOM.render()`を呼んで以前と違う出力をさせることです。

```JSX
function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(
    element,
    document.getElementById('root')
  );
}

setInterval(tick, 1000);
```

**[CodePenで試す](https://codepen.io/gaearon/pen/gwoJZk?editors=0010)**

この章では、この`Clock`コンポーネントを本当の意味で再利用可能でカプセル化された状態にする方法を学びます。進化した後の`Clock`は、自分でタイマーを設定し、一秒ごとに自身を更新するようになります。

はじめに、時計の見た目をカプセル化してみましょう。

```JSX
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);
```
**[CodePenで試す](https://codepen.io/gaearon/pen/dpdoYR?editors=0010)**

しかし、これではある決定的な要求が満たされていません。それは、タイマーを持ち、毎秒UIを更新するという動きを`Clock`の内部に実装したい、というものです。

理想的には、以下のコードを１度書くだけで`Clock`が自分で動き始めるようにしたいはずです。

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

これを実装するには、`Clock`コンポーネントに「state」を足す必要があります。

stateはpropsに似ていますが、プライベート変数で、完全にコンポーネントによってコントロールされています。

以前の章で「Classコンポーネントには追加機能がある」お話をしましたが、この「state」がそれです。

### functionをClassに書き換える

`Clock`のようなfunctionコンポーネントをClassコンポーネントに変えるには、以下の５ステップが必要です。

1.　元の関数と同名のES6のclassを作り、`React.Component`を継承させる
2.　`render()`という名前の空のメソッドを足す
3.　元の関数の中身を`render()`メソッドの中に移動する
4.　`render()`内の`props`を`this.props`に書き換える
5.　空になった関数宣言を削除する

```JSX
class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}
```
**[CodePenで試す](https://codepen.io/gaearon/pen/zKRGpo?editors=0010)**

これで`Clock`はclassとして定義されました。

`render`メソッドは更新が起こるたびに呼び出されますが、`Clock`が同じDOMノードにレンダリングされている限り、使われる`Clock`インスタンスは１つです。stateやライフサイクル・メソッドなどの追加機能が使えるのはそのためです。

### Classにstateを足す

以下の３ステップで`date`をpropsからstateに移動します。

1. `render()`メソッドの`this.props.date`を`this.state.date`に変える

```JSX
class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}
```

2. `this.state`を初期化するコンストラクタを追加する

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

親クラスのコンストラクタにpropsを渡している点に注意してください。classコンポーネントでは常にこの処理も書くべきです。

3.　`<Clock />`　elementから　`date`属性を削除する

```JSX
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')
);
```
**[CodePenで試す](https://codepen.io/gaearon/pen/KgQpJd?editors=0010)**

次に、`Clock`が自身でタイマーをセットし自身を更新できるようにします。

### Classにライフサイクル・メソッドを追加する
多数のコンポーネントを持つアプリケーションにとっては、破棄したコンポーネントが専有していたリソースを開放することが非常に重要です。


`Clock`がDOMに始めてレンダリングされた時にはタイマーがセットされるようにしたいとします。このタイミングは、Reactでは「マウント」と呼びます。

さらに、`Clock`に生成されたDOMが削除されたとき、そのタイマーを消去したいとします。このタイミングは、Reactでは「アンマウント」と呼びます。

コンポーネントがマウント、またはアンマウントされた時に何かのコードを実行したい場合、専用の名前をもったメソッドを定義します。

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

  componentDidMount() {

  }

  componentWillUnmount() {

  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}
```
これらのメソッドは「ライフサイクルメソッド」と呼ばれます。

`componentDidMount()`メソッドは、コンポーネントの出力がDOMにレンダリングされた時に実行されます。タイマーをセットするのにピッタリなタイミングです。

```JSX
componentDidMount() {
  this.timerID = setInterval(
    () => this.tick(),
    1000
  );
}
```

`this`に直接タイマーのIDを保存していることに注目してください。

`this.props`はReactによって設定されますし、`this.state`は特別な意味を持っています。が、データの流れに関与しない何か、例えばタイマーIDを保存するために他の変数を設定するのは自由です。

`componentWillUnmount()`メソッドでタイマーを破棄します。


```JSX
componentWillUnmount() {
  clearInterval(this.timerID);
}
```

最後に、`Clock`コンポーネントが毎秒実行する`tick()`（※）メソッドを実装します。

※訳注 : 秒針がカチカチいう時の「カチッ」を表す英語

コンポーネントのstateを更新するため、`tick()`は`this.setState()`を利用します。

```JSX
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>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);
```
**[CodePenで試す](https://codepen.io/gaearon/pen/amqdNA?editors=0010)**

これで、この時計は毎秒カチカチと進むようになりました。

何が起きていて、メソッドがどのような順番で実行されているのか、軽くおさらいしましょう。

1. `<Clock />` が`ReactDOM.render()`に渡されたとき、Reactは`Clock`コンポーネントのコンストラクタを呼びます。`Clock`は現在の時間を表示する必要があるので、自分の状態`this.state`を現在時間を含むオブジェクトで初期化します。このstateは後で更新されます。
2. Reactは`Clock`コンポーネントの`render()`メソッドを呼びます。これによってReactは画面に表示すべきものを知ります。そのあと、Reactは`Clock`のrender出力に合致するようDOMを更新します。
3. `Clock`の出力がDOMに挿入されたとき、ReactはClockの`componentDidMount()`メソッドを呼びます。その中で`Clock`コンポーネントはブラウザに対し、自身の`tick()`メソッドを毎秒呼び出すタイマーをセットするよう頼みます。
4. ブラウザは一秒ごとに`tick()`を呼びます。`Clock`コンポーネントは`tick()`の中で`setState()`に現在時刻を渡して呼び、`this.date`を更新します。このsetState()呼出しのおかげて、Reactはstateが変わったことに気づき、render()を再度呼んで変更点を調べます。今回は`render()`内で`this.state.date`が変化しているので、render出力も異なるものとなり、Reactはそれを反映させるべくDOMを更新します。
5. もし`Clock`コンポーネントがDOMから除去されれば、Reactは`componentWillUnmount()`メソッドを呼び出し、タイマーは止まります。


### stateを正しく使う
以下は`setState()`について知っておいて欲しいことです。

#### stateを直接変更してはいけない
例えば、これではコンポーネントは再描画されません。

```JSX
// 間違い
this.state.comment = 'Hello';
```
代わりに`setState()`を使ってください。

```JSX
// 正解
this.setState({comment: 'Hello'});
```
`this.state`に直接代入することが許されるのは、コンストラクタだけです。

#### stateの更新は非同期の場合がある
パフォーマンス向上のため、Reactは複数の`setState()`呼び出しへの対応を一度のバッヂ処理で済ませることがあります。

`this.props`と`this.state`は非同期的に更新される場合もあるので、これらに依存して次の状態を計算するべきではありません。

例えば、以下のコードではカウンターの更新に失敗する可能性があります。

```JSX
// 間違い
this.setState({
  counter: this.state.counter + this.props.increment,
});
```
修正するには、`setState()`の別の使い方を利用します。引数に関数を渡すと、その関数は以前のstateを第一引数に、更新時のpropsを第二引数にとって実行されます。

```JSX
// 正解
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
```
上ではアロー関数を使いましたが、通常の関数でも動作します。

```JSX
// 正解
this.setState(function(state, props) {
  return {
    counter: state.counter + props.increment
  };
});
```
#### stateの更新はマージされる
`setState()`を呼んだとき、Reactは現在の`state`と渡されたオブジェクトをマージします。

stateがいくつかの独立した変数を持っている場合を例にとりましょう。

```JSX
constructor(props) {
  super(props);
  this.state = {
    posts: [],
    comments: []
  };
}
```
別々の`setState()`呼び出しを使って、それぞれの変数を独立して更新することができます。

```JSX
  componentDidMount() {
    fetchPosts().then(response => {
      this.setState({
        posts: response.posts
      });
    });

    fetchComments().then(response => {
      this.setState({
        comments: response.comments
      });
    });
  }
```
このマージはshallow（浅いマージ）なので、`this.setState({comments})`によって

- `this.state.posts`は全く変化しない
- `this.state.comments`の中はまるごと入れ替わる

ことになります。

### データは下に流れる
あるコンポーネントがステートフル(stateを持っている)かステートレスなのかは、その親コンポーネントにとっても子コンポーネントにとっても知りえないことですし、また自分の親や子がfunctionコンポーネントなのかClassコンポーネントなのかも気にするべきではありません。

これが、stateがしばしば「ローカル」だとか「カプセル化されている」と言われる理由です。stateはそれを保持しセットするコンポーネント自身以外からはアクセスできません。

コンポーネントは、自身のstateを子コンポーネントにpropsとして渡す場合があります。

```JSX
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
```

これはユーザーが定義したコンポーネントでも可能です。

```JSX
<FormattedDate date={this.state.date} />
```
`FormattedDate`コンポーネントは`date`をpropsとして受け取りますが、それが例えば`Clock`のstateだったのか、`Clock`のpropsだったのか、直接JSXに書かれていたのかはわかりません。

```JSX
function FormattedDate(props) {
  return <h2>It is {props.date.toLocaleTimeString()}.</h2>;
}
```
**[CodePenで試す](https://codepen.io/gaearon/pen/zKRqNB?editors=0010)**

この流れはしばしば「トップダウン」とか「単方向の(unidirectional)」データフローと呼ばれます。全てのstateは特定のコンポーネントに属しており、そのstateから生成されたデータやUIは全て、その子孫のコンポーネントにしか影響を与えません。

コンポーネントのツリー構造を「propsが流れる滝」に例えるなら、各コンポーネントのstateは任意の点で合流する水源であり、合流地点から下流へと流れていきます。

全てのコンポーネントが本当に独立していることを示すために、３つの`<Clock>`をレンダリングする`App`を作ってみましょう。

```JSX
function App() {
  return (
    <div>
      <Clock />
      <Clock />
      <Clock />
    </div>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
```
**[CodePenで試す](https://codepen.io/gaearon/pen/vXdGmd?editors=0010)**

それぞれの`Clock`は各自のタイマーを持ち、独立して自身を更新しています。

Reactアプリケーションでは、コンポーネントがステートフルかステートレスかはコンポーネントの実装の問題であり、変わっていくものです。ステートレスなコンポーネントの内部でステートフルなコンポーネントを利用することは可能ですし、逆もまた然りです。

# 6.イベントハンドリング
*React elementでのイベントハンドリングは、DOMのそれとそっくりです。ただ、いくつか文法上の違いがあります。*

- Reactのイベントは「全て小文字」ではなくキャメルケースで命名されています
- JSXでのイベントハンドラーは、文字列ではなく関数の形で渡します

例えば、HTMLでの以下の例が、

```HTML
<button onclick="activateLasers()">
  Activate Lasers
</button>
```
Reactではこうなります。

```JSX
<button onClick={activateLasers}>
  Activate Lasers
</button>
```


もう１つの違いは、`false`を渡しても「デフォルトのハンドラを無効化」(prevent default)できないことです。そのためには、ハンドラーの中で明示的に`preventDefault`を呼びます。
例えば、Reactを使わない素のHTMLでリンクによる遷移を止めるときは、以下のように書けるでしょう。

```HTML
<a href="#" onclick="console.log('The link was clicked.'); return false">
  Click me
</a>
```
Reactでは代わりに以下のように書きます。

```JSX
function ActionLink() {
  function handleClick(e) {
    e.preventDefault();
    console.log('The link was clicked.');
  }

  return (
    <a href="#" onClick={handleClick}>
      Click me
    </a>
  );
}
```

`e`はシンセティック・イベント (Synthetic events※) です。Reactは[W3Cの仕様](https://www.w3.org/TR/DOM-Level-3-Events/)に準拠してシンセティック・イベントを定義するので、ブラウザ互換性の心配はありません。詳しくは[シンセティック・イベントについてのリファレンス](https://reactjs.org/docs/events.html)をご覧ください。

※訳注 たぶんブラウザネイティブのイベントに対するReactのWrapper。W3Cの仕様通りの実装でないブラウザでも、仕様どおりの名前をセットすれば相当するイベントを内部的に呼んでくれる。

Reactでは基本的に、生成済みのDOMに`addEventListener`でリスナを登録するべきではありません。代わりに、要素が最初にレンダリングされる時にリスナを用意します。

コンポーネントをES6のClassで定義するときによくあるパターンは、イベントハンドラーをメソッドとして定義することです。例えばこの`Toggle`コンポーネントはクリックで「ON」と「OFF」の表示を行き来します。

```JSX
class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // このbind()はコールバックでthisを動作させるために必要
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(state => ({
      isToggleOn: !state.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

ReactDOM.render(
  <Toggle />,
  document.getElementById('root')
);
```
**[CodePenで試す](https://codepen.io/gaearon/pen/xEmzGg?editors=0010)**

JSXのコールバックにおけるthisの意味に気をつけてください。JavaScriptのデフォルトでは、クラスメソッドのthisは束縛されていません。`this.handleClick`をbindせずに`onClick`に渡すと、実際に関数が呼ばれた時に`this`は`undefined`になります。

これはReactに限った挙動ではなく、JavaScriptの関数の挙動です。`onClick={this.handleClick}`のように`()`を後ろにつけずに関数に言及するときは、一般的にbindしたほうが良いでしょう。

`bind`を呼ぶ作業にイラっとするあなたには、２つの回避法があります。
実験的な[public class fields syntax](https://babeljs.io/docs/en/babel-plugin-proposal-class-properties)で書くなら、class fieldsを使って正しくコールバックをbindできます。

```JSX
class LoggingButton extends React.Component {
  // この構文でthisを確実にhandleClickに束縛できます
  // 警告: これは実験的な文法です
  handleClick = () => {
    console.log('this is:', this);
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    );
  }
}
```

この構文はCreate React Appではデフォルトで有効です。

また、コールバックでアロー関数を使うことも有効です。

```JSX
class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }

  render() {
    // この構文でthisを確実にhandleClickに束縛できます
    return (
      <button onClick={(e) => this.handleClick(e)}>
        Click me
      </button>
    );
  }
}
```
この構文の問題は、`LoggingButton`がレンダリングされるたびに別々のコールバックが作り直されるという点です。多くのケースでは問題ありませんが、このコールバックがpropsとして下位のコンポーネントに渡されている場合、余計な再レンダリングを招くかもしれません。このパフォーマンスの問題を避けるために、一般的にはclass fields syntaxを使うことをお勧めします。

### イベントハンドラに引数を渡す
ループの中ではイベントハンドラーに追加の引数を渡すことがよくあります。例えば`id`が生のIDを指すなら、以下のどちらでも動作します。

```JSX
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
```
上の２行はそれぞれアロー関数と`Function.prototype.bind`を使っていて、等価です。

どちらのケースでも、Reactイベントを表す引数`e`はIDの次の第二引数として渡されています。アロー関数では明示的に渡す必要がありますが、`bind`では追加の引数は自動的に渡されます。

# 7.条件付きレンダリング
*Reactでは、望む振る舞いをカプセル化した状態で保持するコンポーネントを作ることができます。そして、その振る舞いの中からアプリケーションの状態によって必要なものだけを実際にレンダリングできます。*

Reactでの条件付きレンダリング（Conditional rendering）は、JavaScriptの条件式と同じように動作します。JavaScriptの`if`や条件演算子を使ってその瞬間の状態に応じたelementを作り、ReactにUIを更新させてください。

下の２つのコンポーネントを考えてみましょう。

```JSX
function UserGreeting(props) {
  return <h1>Welcome back!</h1>;
}

function GuestGreeting(props) {
  return <h1>Please sign up.</h1>;
}
```

加えて`Greeting`コンポーネントを作成しましょう。ユーザーがログインしているかによって、上２つのコンポーネントのうちどちらかを表示します。

```JSX
function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
}

ReactDOM.render(
  // isLoggedIn={true}に変えて試してみてください
  <Greeting isLoggedIn={false} />,
  document.getElementById('root')
);
```
**[CodePenで試す](https://codepen.io/gaearon/pen/ZpVxNq?editors=0011)**

この例では`isLoggedIn`propsの値によって異なる挨拶をレンダリングします。

#### element変数
変数にelementを格納することも可能です。これにより、他の部分の出力を変えないままコンポーネントの一部を条件的にレンダリングすることが可能です。

ログインボタンとログアウトボタンを表す２つのコンポーネントを考えてみましょう。

```JSX
function LoginButton(props) {
  return (
    <button onClick={props.onClick}>
      Login
    </button>
  );
}

function LogoutButton(props) {
  return (
    <button onClick={props.onClick}>
      Logout
    </button>
  );
}

```

下の例では、`LoginControl`というステートフルなコンポーネントを作ります。

`LoginControl`は自身の現在のstateによって`<LoginButton />``<LogoutButton />`を表示し、また先程の例の`<Greeting />`を表示します。

```JSX
class LoginControl extends React.Component {
  constructor(props) {
    super(props);
    this.handleLoginClick = this.handleLoginClick.bind(this);
    this.handleLogoutClick = this.handleLogoutClick.bind(this);
    this.state = {isLoggedIn: false};
  }

  handleLoginClick() {
    this.setState({isLoggedIn: true});
  }

  handleLogoutClick() {
    this.setState({isLoggedIn: false});
  }

  render() {
    const isLoggedIn = this.state.isLoggedIn;
    let button;

    if (isLoggedIn) {
      button = <LogoutButton onClick={this.handleLogoutClick} />;
    } else {
      button = <LoginButton onClick={this.handleLoginClick} />;
    }

    return (
      <div>
        <Greeting isLoggedIn={isLoggedIn} />
        {button}
      </div>
    );
  }
}

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

```
**[CodePenで試す](https://codepen.io/gaearon/pen/QKzAgB?editors=0010)**

このように変数を宣言し`if`文を書いて条件付きレンダリングを行っても良いですが、より短い構文を使いたいこともあるでしょう。以下でJSXにインラインで条件を設定する方法を説明します。

####　`&&`論理演算子を用いたインラインのif文
JSXにはどんな式でも波括弧で囲んで埋め込むことができます。`&&`論理演算子も同様です。条件付きでelementを挿入する場合に便利です。

```JSX
function Mailbox(props) {
  const unreadMessages = props.unreadMessages;
  return (
    <div>
      <h1>Hello!</h1>
      {unreadMessages.length > 0 &&
        <h2>
          You have {unreadMessages.length} unread messages.
        </h2>
      }
    </div>
  );
}

const messages = ['React', 'Re: React', 'Re:Re: React'];
ReactDOM.render(
  <Mailbox unreadMessages={messages} />,
  document.getElementById('root')
);
```
**[CodePenで試す](https://codepen.io/gaearon/pen/ozJddz?editors=0010)**

これが動作するのは、`true && （式）`は常に`（式）`として評価され、`false && （式）`は常に`false`として評価されるからです。

そのため、条件式が`true`なら、`&&`直後のelementは出力に現れます。falseなら、Reactは無視します。

#### インラインのif-else + 三項演算子
条件付きのレンダリングをinlineで行うもう一つの方法は、JavaSciptの三項演算子`条件 ? true : false`を使うことです。

以下の例では、条件付きで小さなテキストブロックを表示しています。

```JSX
render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
    </div>
  );
}
```

より大きな式で使うことも可能ですが、何が起きているのかは分かりにくくなります。

```JSX
render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      {isLoggedIn ? (
        <LogoutButton onClick={this.handleLogoutClick} />
      ) : (
        <LoginButton onClick={this.handleLoginClick} />
      )}
    </div>
  );
}
```

JavaScriptの場合と同様、自分のチームにとっての読みやすさを考え、適切なスタイルを決めるのはあなたです。ただ、条件式が複雜になりすぎたら、コンポーネントを分割するタイミングかもしれないことを覚えておきましょう。

#### コンポーネントのレンダリングを止める
稀に、他のコンポーネントによってrenderされたコンポーネントに、自分自身を隠して欲しい場合があります。これを実現するには、レンダリング出力の代わりに`null`を返します。

以下の例で、`<WarningBanner />`は`warn`というpropsの値に従ってレンダリングされます。`warn`が`false`なら、コンポーネントはレンダリングされません。

```JSX
function WarningBanner(props) {
  if (!props.warn) {
    return null;
  }

  return (
    <div className="warning">
      Warning!
    </div>
  );
}

class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = {showWarning: true};
    this.handleToggleClick = this.handleToggleClick.bind(this);
  }

  handleToggleClick() {
    this.setState(state => ({
      showWarning: !state.showWarning
    }));
  }

  render() {
    return (
      <div>
        <WarningBanner warn={this.state.showWarning} />
        <button onClick={this.handleToggleClick}>
          {this.state.showWarning ? 'Hide' : 'Show'}
        </button>
      </div>
    );
  }
}

ReactDOM.render(
  <Page />,
  document.getElementById('root')
);
```
**[CodePenで試す](https://codepen.io/gaearon/pen/Xjoqwm?editors=0010)**

コンポーネントの`render`メソッドが`null`を返しても、そのコンポーネントのライフサイクルメソッドの発火には影響がありません。例えば`componentDidUpdate`は呼ばれます。

# 8.リストとキー
訳注:本章の「リスト」は単に複数のモノが並んだ集合という意味の英語で、特定の機能や関数を指していません。

*はじめに、JavaScriptでリストを編集する方法をおさらいしましょう*

以下のコードでは、配列`numbers`を`map()`関数に渡して値を２倍にし、`doubled`に格納してからログに出力しています。

```JSX
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((number) => number * 2);
console.log(doubled);
```
このコードはコンソールに`[2, 4, 6, 8, 10]`を表示します。

Reactで単なる配列をelementのリストに変換する方法は、これに良く似ています。

####　複数のコンポーネントをレンダリングする
elementの集合も、JSXに波括弧`{}`で埋め込むことでビルドすることができます。

以下では、`numbers`配列をJavaScriptのmap()関数を使ってループさせています。配列の１要素につき１つの`<li>`要素を帰ります。最後に、出来上がったelementの配列を`listItems`に代入します。

```JSX
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li>{number}</li>
);
```

`<ul>`の中に`listItems`配列全体を埋め込み、DOMにレンダリングします。

```JSX
ReactDOM.render(
  <ul>{listItems}</ul>,
  document.getElementById('root')
);
```
**[CodePenで試す](https://codepen.io/gaearon/pen/GjPyQr?editors=0011)**

このコードは箇条書きのリストで1-5までの数字を表示します。


#### 基本的なリストコンポーネント
通常、リストはコンポーネントの中でレンダリングしたいことが多いでしょう。
先程の例は、配列`numbers`を受け取って順番なしのelementのリストを出力する形にリファクタリングできます。

```JSX
function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li>{number}</li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);
```

このコードを実行すると、list itemsにはkeyが必要だという警告が表示されます。「key」とは、elementのリストを作る時に含めなければならない特別な文字列です。なぜこれが重要なのかは、次の章で扱います。

`numbers.map()`の中でlistItemsにkeyを埋め込んで、この問題を解決しましょう。

```JSX
function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li key={number.toString()}>
      {number}
    </li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

```
**[CodePenで試す](https://codepen.io/gaearon/pen/jrXYRR?editors=0011)**

#### key
keyはReactが変更されたまたは削除された要素を特定するのを助けます。elementの安定したIDとして機能させるため、keyは配列の内部で渡すべきです。

```JSX
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li key={number.toString()}>
    {number}
  </li>
);
```

要素のkeyを選ぶ一番良い方法は、兄弟要素と区別できるユニークな文字列を使うことです。データの内容をkeyとして使うことが多いでしょう。

```JSX
const todoItems = todos.map((todo) =>
  <li key={todo.id}>
    {todo.text}
  </li>
);
```

信頼できるIDとして使えるものがないときは、最後の手段としてインデックスを使っても良いでしょう。

```JSX
const todoItems = todos.map((todo, index) =>
  // リストの要素から安定したIDが取れない場合だけ利用
  <li key={index}>
    {todo.text}
  </li>
);
```

リスト要素の順序が変わる可能性がある場合は、インデックスの利用はお勧めしません。パフォーマンスを低下させたり、コンポーネントの状態に問題を起こします。keyを設定しなければ、Reactはデフォルトとしてインデックスをkeyとして利用します。

#### keyを持つコンポーネントを抽出する
keyはそれを内包している配列の中でのみ意味を持ちます。

例えば`ListItem`コンポーネントを抽出するなら、keyは`ListItem`自体の中の`li`ではなく、`<ListItem />`で設定するべきです。

```JSX
function ListItem(props) {
  const value = props.value;
  return (
    // 間違い! keyはここで指定する必要はない
    <li key={value.toString()}>
      {value}
    </li>
  );
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // 間違い! keyはここで指定されるべき
    <ListItem value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

```
正しい例は以下です

```JSX
function ListItem(props) {
  // 正解! ここでkeyを指定する必要はない
  return <li>{props.value}</li>;
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // 正解! keyは配列の内部で指定するべき
    <ListItem key={number.toString()}
              value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);
```
**[CodePenで試す](https://codepen.io/gaearon/pen/ZXeOGM?editors=0010)**

経験則として、map()関数呼び出しの中にあるelementはkeyを必要としていることが多くなります。
　　　　　　　　　　　　　　
#### keyは兄弟要素の中で一意でなければならない
配列の中で使われるkeyは兄弟要素の中で一意である必要があります。しかし、グローバルに一意である必要はありません。２つの異なる配列で同じkeyを使うことは可能です。

```JSX
function Blog(props) {
  const sidebar = (
    <ul>
      {props.posts.map((post) =>
        <li key={post.id}>
          {post.title}
        </li>
      )}
    </ul>
  );
  const content = props.posts.map((post) =>
    <div key={post.id}>
      <h3>{post.title}</h3>
      <p>{post.content}</p>
    </div>
  );
  return (
    <div>
      {sidebar}
      <hr />
      {content}
    </div>
  );
}

const posts = [
  {id: 1, title: 'Hello World', content: 'Welcome to learning React!'},
  {id: 2, title: 'Installation', content: 'You can install React from npm.'}
];
ReactDOM.render(
  <Blog posts={posts} />,
  document.getElementById('root')
);
```
**[CodePenで試す](https://codepen.io/gaearon/pen/NRZYGN?editors=0010)**

keyはReactにとってのヒントとなりますが、コンポーネントには渡されません。コンポーネント内でkeyと同じ値が必要であれば、明示的にpropsとして渡してください。

```JSX
const content = posts.map((post) =>
  <Post
    key={post.id}
    id={post.id}
    title={post.title} />
);

```

上記の例では、`Post`コンポーネントは`props.id`を読み取れますが、`props.key`は読み取れません。

#### JSXに埋め込まれたmap()
上記の例では、`listItems`変数を個別に宣言し、JSXに埋め込みました。


```JSX
function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <ListItem key={number.toString()}
              value={number} />

  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

```

JSXでは波括弧の中に任意の式を埋め込めるので、map()をインラインで設定することも可能です。

```JSX
function NumberList(props) {
  const numbers = props.numbers;
  return (
    <ul>
      {numbers.map((number) =>
        <ListItem key={number.toString()}
                  value={number} />

      )}
    </ul>
  );
}

```


これが明快なコードにつながることもありますが、使いすぎもありえます。JavaScriptと同じく、その変数を切り出すことでコードが読みやすくなるのかは自由に判断してください。ただし、`map()`の中のネストが深くなったら、コンポーネントを分割する良い機会かも知れません。

# 9.フォーム
*内部的な状態を保持する必要性から、HTMLのform要素はReactにおいて他の要素と少し違った動きをします。例えば、素のHTMLで書いたこのフォームは１つの名前を受け取ります*

```JSX
<form>
  <label>
    Name:
    <input type="text" name="name" />
  </label>
  <input type="submit" value="Submit" />
</form>

```

ユーザーがフォームを送信したとき、このフォームはHTMLのデフォルト通り新しいページを表示します。同じ挙動をReactで実現したければ可能です。しかし多くの場合、フォームの送信を検知して、ユーザーが入力したデータにアクセスできるJavaScript関数がある方が便利でしょう。それを実現する標準的な方法は、「制御されたコンポーネント(controlled components)」と呼ばれるテクニックです。

### 制御されたコンポーネント

HTMLでは、`<input>`、`<textarea>`、`<select>`といったフォーム要素は、典型的には自身の状態を管理し、ユーザー入力に従って更新します。Reactでは、可変の状態は典型的にはコンポーネントのstateプロパティに格納され、`setState()`によってのみ更新されます。

Reactのstateを「唯一の信頼する情報源（single source of truth）」とすることで、この２つを合体させることができます。そうすれば、フォームをレンダリングするReactコンポーネントは後のユーザー入力への対応まで制御することができます。このような形で値をReactに制御されたinput要素が「制御されたコンポーネント」と呼ばれます。

TODO フォームの章を訳す

## 10.stateを上流へ伝える
*同じ可変のデータを反映させるコンポーネントはしばしば数個になります。おすすめの方法は、共有するstateを一番近い共通の祖先まで上げる(Lifting　up)ことです。実際の動きを見てみましょう。*

この章では、特定の温度で水が沸騰するかを求める温度計算機を作ります。

まずは`BoilingVerdict`というコンポーネントから始めます。このコンポーネントは`celsius`温度をpropsとして受け取り、水が沸騰するのに十分かどうかを出力します。

※訳注:BoilingVerdict=沸騰判定　　celsius=摂氏

```JSX
function BoilingVerdict(props) {
  if (props.celsius >= 100) {
    return <p>The water would boil.</p>;
  }
  return <p>The water would not boil.</p>;
}
```

次に`Calculator`コンポーネントを作ります。このコンポーネントは、ユーザーが温度を入力する`<input>`要素をレンダリングし、値を`this.state.temperature`に格納します。加えて、現在の温度に基づいて`BoilingVerdict`をレンダリングします。

```JSX
class Calculator extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {temperature: ''};
  }

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

  render() {
    const temperature = this.state.temperature;
    return (
      <fieldset>
        <legend>Enter temperature in Celsius:</legend>
        <input
          value={temperature}
          onChange={this.handleChange} />

        <BoilingVerdict
          celsius={parseFloat(temperature)} />

      </fieldset>
    );
  }
}
```

### ２つ目のinputを追加する
新しい要求が来ました。摂氏での入力に加えて華氏での入力も受け付け同期させたい、というものです。手始めに、`Calculator`から`TemperatureInput`コンポーネントを抽出しましょう。`c`か`f`の値を取る`scale`（単位）propsを追加します。

```JSX
const scaleNames = {
  c: 'Celsius',
  f: 'Fahrenheit'
};

class TemperatureInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {temperature: ''};
  }

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

  render() {
    const temperature = this.state.temperature;
    const scale = this.props.scale;
    return (
      <fieldset>
        <legend>Enter temperature in {scaleNames[scale]}:</legend>
        <input value={temperature}
               onChange={this.handleChange} />
      </fieldset>
    );
  }
}

```
これで`Calculator`を２つの別々の温度入力欄をレンダリングするよう変更できます。

```JSX
class Calculator extends React.Component {
  render() {
    return (
      <div>
        <TemperatureInput scale="c" />
        <TemperatureInput scale="f" />
      </div>
    );
  }
}

```
**[CodePenで試す](https://codepen.io/gaearon/pen/jGBryx?editors=0010)**

これで２つの入力欄ができましたが、片方に入力しても他方は更新されません。これでは要求と矛盾します。同期させたいのです。

また、`Calculator`は`BoilingVerdict`を表示できません。現在の温度は`TemperatureInput`の中に隠されているので、`Calculator`は知らないのです。

### 変換関数を書く
まず、摂氏と華氏を相互に変換する２つの関数を書きます。

```JSX
function toCelsius(fahrenheit) {
  return (fahrenheit - 32) * 5 / 9;
}

function toFahrenheit(celsius) {
  return (celsius * 9 / 5) + 32;
}

```

これら２つの関数は数を変換します。さらに、文字列`temperature`を受け取る関数と、文字列を返す関数を作りましょう。一方の入力から他方の値を計算するのに使います。

無効な`temperature`を受け取ると空文字を返します。出力は小数点以下３位で切り捨てられます。

```JSX
function tryConvert(temperature, convert) {
  const input = parseFloat(temperature);
  if (Number.isNaN(input)) {
    return '';
  }
  const output = convert(input);
  const rounded = Math.round(output * 1000) / 1000;
  return rounded.toString();
}
```

例えば`tryConvert('abc', toCelsius)`は空文字を返し、`tryConvert('10.22', toFahrenheit)`は`'50.396'`を返します。

### stateを上げる
現在、`TemperatureInput`コンポーネントはそれぞれ独立したローカルなstateに値を保持しています。

```JSX
class TemperatureInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {temperature: ''};
  }

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

  render() {
    const temperature = this.state.temperature;
    // ...
```

しかし、この２つは互いに同期して欲しいところです。摂氏の入力を変えると華氏のほうは変換された温度を示し、逆もそうなるように。

Reactでは、stateの共有はそれを必要とするコンポーネントの一番近い共通の祖先まで移動させることで実現します。これを「stateを上げる（lifting state up）」と呼びます。今回は、`TemperatureInput`のローカルなstateを`Calculator`に移動します。

`Calculator`が共通の状態を保持すれば、両方の入力欄にとっての「情報源(source of truth)」となります。このstateに、双方が同期した値を持つよう教えることができます。`TemperatureInput`のpropsは同じ親である`Calculator`コンポーネントから来ているので、２つの入力は常に同期されます。

どのように動作するか、一歩づつ見ていきましょう。

まず、`TemperatureInput`コンポーネントの中で`this.state.temperature`を`this.props.temperature`に変更します。後ほど`Calculator`から渡してやる必要はありますが、今は`this.props.temperature`が既にあるものとして扱いましょう。

```JSX
  render() {
    // 改造前: const temperature = this.state.temperature;
    const temperature = this.props.temperature;
    // ...

```

ご存知の通り、porpsは読み取り専用です。`temperature`がローカルステートだったときは、`TemperatureInput`は単に`this.setState()`でそれを更新できました。今、`temperature`は親からpropsとして渡されているので、`TemperatureInput`には操作できません。

Reactでは、通常これはコンポーネントを「制御された(controlled)」状態にすることで実現します。DOMの`<input>`が`value`と`onChange`の両方のpropsを受け付けるように、`TemperatureInput`が`temperature`と`onTemperatureChange`を`Calculator`から受け取れるようにします。

こうすると、`TemperatureInput`が温度を更新したいときは、`this.props.onTemperatureChange`を呼びます。

```JSX
  handleChange(e) {
    // Before: this.setState({temperature: e.target.value});
    this.props.onTemperatureChange(e.target.value);
    // ...
```


















---
この記事はReact公式サイト 　https://reactjs.org/ の部分的な和訳です。
Copyright © 2018 Facebook Inc.