[Get started]から始めるReact開発：その3:Components and Props

さらに[React](https://facebook.github.io/react/docs/components-and-props.html)

[[Get started]から始めるReact開発：その1](http://qiita.com/t-katsura/items/6c3a92583b8a738e2921)
[[Get started]から始めるReact開発：その2:Rendering Elements](http://qiita.com/t-katsura/items/43ac2e758fd53a8a9ffa)
[[Get started]から始めるReact開発：その3:Components and Props](http://qiita.com/t-katsura/items/d3c320a0b68cee7c9d77)
[[Get started]から始めるReact開発：その4(State and Lifecycle①](http://qiita.com/t-katsura/items/7b8e4889fe73e4d3245d)
[[Get started]から始めるReact開発：その4(State and Lifecycle②](http://qiita.com/t-katsura/items/24a14ff763ac7738a036)

#Components and Props

コンポーネントはUIを独立した再利用できるピースに分けることができ、個別のそれぞれのピースについて考えることができます。

##Functional and Class Components

コンポーネントを定義する最もシンプルな方法はjavascript関数を書くことです。

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

この関数はデータとしての`props`オブジェクトを引数として利用し、`React要素`を返すのでReactコンポーネントとして妥当なものです。
私たちはそのようなコンポーネントのことを文字通り`javascript funnction`なので"functional"と呼びます。
あなたはまた、コンポーネントの定義に`ES6 class`を使うこともできます。

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

上記二つのコンポーネントは、`React`という観点で見れば同じものです。
クラスについては次のセクションで議論するだろう追加の特徴がいくつかあります。
それまでは`functional component`については簡潔に利用することにしましょう。

##Rendering a Component

以前、私たちはDOMタグを代表するReact要素のみに出会っていました。

```javascript:code
const element = <div />;
```

しかしながら、要素はユーザー定義コンポーネントも代表することができます。

```javascript:code
const element = <Welcome name="Sara" />;
```

ユーザー定義コンポーネントを代表する要素としてReactを見るときは、単一のオブジェクトとしてこのコンポーネントに`JSX attribute`を渡します。私たちはこのオブジェクトを`props`と呼びます。

例えば、このコードはページ上に`Hello, Sara`を描画します。

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

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

[CodePenで確認](https://codepen.io/gaearon/pen/YGYmEG?editors=0010)

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

1. まず`<Welcome name="Sara" />`と一緒に`ReactDOM.render()`を呼び出します。
2. Reactはpropsとして`{name: 'Sara'}`と一緒に`Welcome`コンポーネントを呼びます。
3. `Welcome`コンポーネントは結果として`<h1>Hello, Sara</h1>`要素をを返します。
4. React DOMは`<h1>Hello, Sara</h1>`に合うように効率的にDOMをアップデートします。

>**警告**
>コンポーネント名は大文字で始める。
>例えば`<div />`はDOMタグを代表していますが、`<Welcome />`はコンポーネントを代表し、`<Welcome />`にスコープがあることを要求します。

##Composing Components

コンポーネントはそれらのアウトプットの中で他のコンポーネントを参照できます。これによりどのレベルの詳細にも同じコンポーネント抽象化を使用できます。ボタン、フォーム、ダイアログ、スクリーン。Reactアプリは全て、それらはコンポーネントとして共通の表現がされます。
例えば、なんども`Welcome`をレンダリングするAppコンポーネントを作れます。

```javascript:code
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://codepen.io/gaearon/pen/KgQKPr?editors=0010)

通常、新しいReact Appsは一番上にシングルAppコンポーネントを持っています。しかしながらもし、既にあるAppにReactを統合する場合は、ボタンのような小さいコンポーネントから逆さまに始まるかもしれないし、徐々にビュー階層の一番上に向かって作業をするかもしれません。

>**警告**
>コンポーネントは単一のルート要素を返さなければなりません。これは全ての`<Welcome />`要素を含むように`<div>`を追加する理由となります。

##Extracting Components

小さなコンポーネントにコンポーネントを分割することを恐れないでください。
例えば`Comment`コンポーネントについて考えます。

```javascript:code
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://codepen.io/gaearon/pen/VKQwEo?editors=0010)

propsとして`auther（オブジェクト）`,`text(文字列)`,`date(date オブジェクト?)`を受け入れて、ソーシャルメディア上でコメントを述べます。
このコンポーネントは全てネストされているため、変更が複雑になりますしそれ自体のいち部分を個別に再利用することも難しくなっています。それではここから幾つかのコンポーネントを抜き出してみましょう。

最初にAvatorを抜き取ってみましょう

```javascript:code
function Avatar(props) {
  return (
    <img className="Avatar"
      src={props.user.avatarUrl}
      alt={props.user.name}
    />
  );
}
```

`Avator`は`Comment`の中でレンダリングされていることを知る必要はありません。これは`auther`ではなくより一般的な名前としての`user`をpropに与えている理由です。

私たちはほんの少しだけコメントをすぐに単純化できます。

```javascript:code
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>
  );
}
```

次に、私たちはuser's nameに隣接する`Avatar`をレンダリングする`UserInfo`コンポーネントを抜き取ってみましょう。

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

これはさらに`Comment`を単純化することができます。

```javascript:code
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://codepen.io/gaearon/pen/rrJNJY?editors=0010)

コンポーネントの抽出は最初は単調な仕事のように見えるが、再利用可能なコンポーネントのパレットを持つことは大きなアプリでこそうまくいく。
大まかに良い方法としては、あなたのUIの一部で幾つかの部品（`Button`や`Panel`や`Avatar`）を使用している場合や、それ自身（`App`, `FeedStory`, `Comment`）が十分に複雑な場合には、再利用可能なコンポーネントの良い候補となります。

##Props are Read-Only

`function`や`class`としてコンポーネントを宣言したとしても、それ自身の`props`を変更してはいけません。`sum`関数について考えます。

```javascript:code
function sum(a, b) {
  return a + b;
}
```

このような関数はそれらの入力の変更を行わず、いつも同じ入力に対して同じ結果を返すので`pure`と呼ばれています。
対象的に、この関数は自身の入力を変更しているので`impure`です。

```javascript:code
function withdraw(account, amount) {
  account.total -= amount;
}
```

Reactはとても柔軟ではありますが、一つ厳格なルールを持っています。

`All React components must act like pure functions with respect to their props.`
全てのReactコンポーネントはそれらのpropsを尊重し純粋関数のように動かなければならない。

もちろん、アプリケーションUIはダイナミックで時間とともに変わります。次のセクションでは`state`の新しいコンセプトを紹介しましょう。
`State`はこのルールに違反することなくユーザーアクションやネットワークレスポンスや他の何かしらに反応して時間とともにそれらの出力を変更することをReactコンポーネントに許します。