Redux Basics (5): Usage with React 翻訳

# **はじめに**
- [Redux Basics (1): Actions 翻訳](http://qiita.com/uramonk/items/28316e20ad6fb7968993)
- [Redux Basics (2): Reducers 翻訳](http://qiita.com/uramonk/items/3bce34db8cfd0587a63b)
- [Redux Basics (3): Store 翻訳](http://qiita.com/uramonk/items/a6cfa3fa7f7c6827c2b1)
- [Redux Basics (4): Data Flow 翻訳](http://qiita.com/uramonk/items/2e8d89ba0829fe657025)
- [Redux Basics (5): Usage with React 翻訳](http://qiita.com/uramonk/items/b4712620690711466b07)

ReduxのBasicsの翻訳の続きです。今回はUsage with Reactの翻訳となります。翻訳で間違いがあると思いますがそこはご了承ください。

翻訳は下記ページの10/1時点のものとなります。
http://redux.js.org/docs/basics/UsageWithReact.html

_翻訳ここから_

# **Reactとの使い方**
開始時から、我々はReactとReduxが関係を持たないことを強調する必要がありました。あなたはReact, Angular, Ember, jQuery, vanilla JavaScriptとともにReduxアプリを書くことができます。

これは、Reduxは[React](http://facebook.github.io/react/)や[Deku](https://github.com/dekujs/deku)のようなライブラリとともに特によく動き、なぜなら状態の関数としてのUIを描画し、ReduxはActionへのレスポンスの中で状態の更新を発行するからです。

我々はシンプルなTodoアプリを構築するためにReactを使います。

# **React Reduxのインストール**
[React bindings](https://github.com/reactjs/react-redux)は標準でReduxを含みません。あなたは明示的にそれらをインストールする必要があります。

```
npm install --save react-redux
```

もしnpmを使わないならば、unpkgから最新のUMDビルド（[development](https://unpkg.com/react-redux@latest/dist/react-redux.js)か[production](https://unpkg.com/react-redux@latest/dist/react-redux.min.js)ビルド）を取ってくると良いでしょう。もしあなたが`<script>`タグを経由してページにそれを追加するならば、UMDビルドは`window.ReactRedux`と呼ばれるグローバルを伝えます。

# **PresentationalコンポーネントとContainerコンポーネント**
ReduxのためのReact bindingsは**分割したPresentationalとContainerコンポーネント**のアイデアを包含します。もしこれらの条件に精通していない場合、[最初にこれについて読み](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0)、それから戻ってきてください。

記事を読み終わりましたか？これらの違いを詳しく述べましょう:

||Presentationalコンポーネント|Containerコンポーネント|
|-----------------:|:------------------|:-------------------|
|目的|どのように物が見えるか（マークアップ、スタイル）|どのようにものが動くか（データの取得、状態の更新）|
|Reduxへの気づき|No|Yes|
|データの読み込み|propsからデータを読み込む|Redux stateへ購読する|
|データの変更|proprsからコールバックを実行する|Redux Actionを実行する|
|書き込み|手によって|たいていReact Reduxによって生成される|

我々が書くコンポーネントの多くは、Presentationalでしょうが、我々は2,3のRedux Storeへそれらを接続するContainerコンポーネントを必要とします。

専門的に言うと、[`store.subscribe()`](http://redux.js.org/docs/api/Store.html#subscribe)を使うことで手でContainerコンポーネントを書くこともできます。我々はこれをするよう忠告しません、なぜなら、React Reduxは手でするのは難しい多くのパフォーマンス最適化をするからです。この理由により、Containerコンポーネントを書くよりもむしろ、我々は以下で見るような、React Reduxによって提供される[`connect()`]()関数を使ってそれらを生成します。

# **コンポーネント階層の設計**
どのように我々が[ルートの状態オブジェクトの形を設計した](http://redux.js.org/docs/basics/Reducers.html)かを覚えていますか？我々が設計したUI階層をそれに調和させる時がきました。これはReduxの特別なタスクではありません。[Reactを考えること](https://facebook.github.io/react/docs/thinking-in-react.html)は過程を説明する偉大なチュートリアルです。

我々の設計指示はシンプルです。我々はTodoアイテムのリストを表示したいです。クリックで、Todoアイテムは完了したとして線を引いて消されます。我々はユーザーが新しいTodoを追加したフィールドを表示したいです。フッターで、我々はすべてを、完了だけを、またはアクティブなTodoのみを表示するためにトグルを表示したいです。

## **Presentationalコンポーネント**
下記のPresentationalコンポーネントとこの要約で明らかになるpropsを見ましょう。

- **`TodoList`**は見えるTodoを表示しているリストです。
    - `todos: Array`は`{ id, text, completed }`の形のTodoアイテムの配列です。
    - `onTodoClick(id: number)`はTodoがクリックされたときに呼び出されるコールバックです。
- **`Todo`**は一つのTodoアイテムです。
    - `text : string`は表示するテキストです。
    - `completed: boolean`はTodoが線を引いて消すかどうかです。
    - `onClick()`はTodoがクリックされたときに呼び出されるコールバックです。
- **`Link`**はコールバックのリンクです。
    - `onClick()`はリンクがクリックされたときに呼び出されるコールバックです。
- **`Footer`**はユーザーが現在見えるTodoを変えたことを示す場所です。
- **`App`**は全てを描画するルートコンポーネントです。

それらは_見た目_を説明しますが、データが_どこから_来るかは知らなく、_どのように_変わるか知りません。それらはただそれらに与えられたものを描画するだけです。もしあなたがReduxから何か他のものへ移住するなら、これらのコンポーネントを正確に同じに保つことができるでしょう。それらはReduxへの依存を持ちません。

## **Containerコンポーネント**
我々はまたReduxへPresentationalコンポーネントを接続するためのいくつかのContainerコンポーネントを必要とします。例えば、`TodoList`のPresentationalコンポーネントはReduxのStoreへ購読し、どのように現在のvisibilityフィルタが適用されるかを示す`visibleTodoList`のようなコンテナを必要とします。visibilityフィルタを変更することは、我々はクリックに適切なActionを呼び出す`Link`を描画する`FilterLink`のContainerコンポーネントを提供します。

- **`VisibleTodoList`**は現在のvisibilityフィルタによりTodoを除去し、`TodoList`を描画します。
- **`FilterLink`**は現在のvisibilityフィルタを取得し、`Link`を描画します。
    - `filter: string`はvisibilityフィルタを表現するものです。

## **他のコンポーネント**
時々、あるコンポーネントがPresentationalコンポーネントかContainerコンポーネントかどうかを話すのは難しいです。例えば、時々フォームと関数はこの小さい場合のように本当に連結しています:

- **`AddTodo`**は“追加”ボタンの入力フィールドです。

専門的に言うと、我々は二つのコンポーネントにそれを分割できますが、このステージでは早すぎます。Presentationとロジックを大変小さなコンポーネントに混ぜ合わせることがいいでしょう。成長したら、どのように分割するかもっと明らかにし、そして混ぜ合わせを解消しましょう。

# **コンポーネントの実装**
コンポーネントを書いてみましょう！我々はPresentationalコンポーネントを始め、そして我々はまだReduxへバインドすることについては考える必要はありません。

## **Presentationalコンポーネント**
これらは全て通常のReactコンポーネントで、我々は詳細は調べません。我々はローカルの状態やライフサイクルメソッドを使うことのない、関数で状態なしのコンポーネントを書きます。これはPresentationalコンポーネントが関数でなくてはならないことを意味しません。この方法でこれらを定義するのにただ簡単です。もし、そしてあなたがローカルの状態やライフサイクルメソッド、パフォーマンス最適化を追加することが必要なとき、あなたはクラスにそれらを変換できます。

**`components/Todo.js`**

```js
import React, { PropTypes } from 'react'

const Todo = ({ onClick, completed, text }) => (
  <li
    onClick={onClick}
    style={{
      textDecoration: completed ? 'line-through' : 'none'
    }}
  >
    {text}
  </li>
)

Todo.propTypes = {
  onClick: PropTypes.func.isRequired,
  completed: PropTypes.bool.isRequired,
  text: PropTypes.string.isRequired
}

export default Todo
```

**`components/TodoList.js`**

```js
import React, { PropTypes } from 'react'
import Todo from './Todo'

const TodoList = ({ todos, onTodoClick }) => (
  <ul>
    {todos.map(todo =>
      <Todo
        key={todo.id}
        {...todo}
        onClick={() => onTodoClick(todo.id)}
      />
    )}
  </ul>
)

TodoList.propTypes = {
  todos: PropTypes.arrayOf(PropTypes.shape({
    id: PropTypes.number.isRequired,
    completed: PropTypes.bool.isRequired,
    text: PropTypes.string.isRequired
  }).isRequired).isRequired,
  onTodoClick: PropTypes.func.isRequired
}

export default TodoList
```

**`components/Link.js`**

```js
import React, { PropTypes } from 'react'

const Link = ({ active, children, onClick }) => {
  if (active) {
    return <span>{children}</span>
  }

  return (
    <a href="#"
       onClick={e => {
         e.preventDefault()
         onClick()
       }}
    >
      {children}
    </a>
  )
}

Link.propTypes = {
  active: PropTypes.bool.isRequired,
  children: PropTypes.node.isRequired,
  onClick: PropTypes.func.isRequired
}

export default Link
```

**`components/Footer.js`**

```js
import React from 'react'
import FilterLink from '../containers/FilterLink'

const Footer = () => (
  <p>
    Show:
    {" "}
    <FilterLink filter="SHOW_ALL">
      All
    </FilterLink>
    {", "}
    <FilterLink filter="SHOW_ACTIVE">
      Active
    </FilterLink>
    {", "}
    <FilterLink filter="SHOW_COMPLETED">
      Completed
    </FilterLink>
  </p>
)

export default Footer
```

**`components/App.js`**

```js
import React from 'react'
import Footer from './Footer'
import AddTodo from '../containers/AddTodo'
import VisibleTodoList from '../containers/VisibleTodoList'

const App = () => (
  <div>
    <AddTodo />
    <VisibleTodoList />
    <Footer />
  </div>
)

export default App
```

## **Containerコンポーネント**
今、あるContainerを作ることによってこれらPresentationalコンポーネントをReduxへ引っ掛ける時です。専門的に言うと、Containerコンポーネントは、Reduxの状態ツリーの一部を読むために[`store.subscribe()`](http://redux.js.org/docs/api/Store.html#subscribe)を使い、描画するためにPresentationalコンポーネントへpropsを提供する、ただのReactコンポーネントです。あなたは手でContainerコンポーネントを書くことができますが、我々は代わりにReact Reduxライブラリの[`connect()`](https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options)関数でContainerコンポーネントを生成することを提案します。`connect()`関数は不必要な再描画を防ぐための多くの便利な最適化を提供します（この一つの結果は、あなたは`shouldComponentUpdate`を実行することの[Reactパフォーマンスの提案](https://facebook.github.io/react/docs/advanced-performance.html)について心配することはありません。）。

`connect()`を使うことで、あなたは、あなたがラッピングするPresentationalコンポーネントへ渡したいpropsへ現在のReduxのStoreの状態をどのように転換するかを説明する`mapStateToProps`と呼ばれる特別な関数を定義する必要があります。例えば、`VisibleTodoList`は`TodoList`に渡すために`todos`を計算することを必要とし、そして我々は`state.visibilityFilter`により`state.todos`を除く関数を定義し、`mapStateToProps`のなかでそれを使います:

```js
const getVisibleTodos = (todos, filter) => {
  switch (filter) {
    case 'SHOW_ALL':
      return todos
    case 'SHOW_COMPLETED':
      return todos.filter(t => t.completed)
    case 'SHOW_ACTIVE':
      return todos.filter(t => !t.completed)
  }
}

const mapStateToProps = (state) => {
  return {
    todos: getVisibleTodos(state.todos, state.visibilityFilter)
  }
}
```

状態を読むことに加えて、ContainerコンポーネントはActionを呼び出します。同様に、あなたは[`dispatch()`](http://redux.js.org/docs/api/Store.html#dispatch)メソッドを受け取り、Presentationalコンポーネントへ差し込みたいpropsのコールバックを返す`mapDispatchToProps()`と呼ばれる関数を定義します。例えば、我々は`TodoList`コンポーネントへ`onTodoClick`と呼ばれるpropを差し込むために`VisibilityTodoList`が欲しく、`TOGGLE_TODO`Actionを呼び出すための`onTodoClick`が欲しいです。

```js
const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}
```

最後に、我々は`connect()`を呼ぶことによって`VisibleTodoList`を作り、これら二つの関数を渡します:

```js
import { connect } from 'react-redux'

const VisibleTodoList = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)

export default VisibleTodoList
```

これらはReact Redux APIの基礎ですが、2,3のショートカットと強力なオプションがあり、我々はあなたに詳細の[ドキュメント](https://github.com/reactjs/react-redux)を確認することを推奨します。あなたがあまりに頻繁に新しいオブジェクトを作る`mapStateToProps`について心配な場合は、あなたは[reselect](https://github.com/reactjs/reselect)で[派生データの作成](http://redux.js.org/docs/recipes/ComputingDerivedData.html)について学ぶとよいでしょう。

下記で定義されたContainerコンポーネントの残りを見つけてください。

**`containers/FilterLink.js`**

```js
import { connect } from 'react-redux'
import { setVisibilityFilter } from '../actions'
import Link from '../components/Link'

const mapStateToProps = (state, ownProps) => {
  return {
    active: ownProps.filter === state.visibilityFilter
  }
}

const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    onClick: () => {
      dispatch(setVisibilityFilter(ownProps.filter))
    }
  }
}

const FilterLink = connect(
  mapStateToProps,
  mapDispatchToProps
)(Link)

export default FilterLink
```

**`containers/VisibleTodoList.js`**

```js
import { connect } from 'react-redux'
import { toggleTodo } from '../actions'
import TodoList from '../components/TodoList'

const getVisibleTodos = (todos, filter) => {
  switch (filter) {
    case 'SHOW_ALL':
      return todos
    case 'SHOW_COMPLETED':
      return todos.filter(t => t.completed)
    case 'SHOW_ACTIVE':
      return todos.filter(t => !t.completed)
  }
}

const mapStateToProps = (state) => {
  return {
    todos: getVisibleTodos(state.todos, state.visibilityFilter)
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}

const VisibleTodoList = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)

export default VisibleTodoList
```

## **他のコンポーネント**
**`containers/AddTodo.j`**

```js
import React from 'react'
import { connect } from 'react-redux'
import { addTodo } from '../actions'

let AddTodo = ({ dispatch }) => {
  let input

  return (
    <div>
      <form onSubmit={e => {
        e.preventDefault()
        if (!input.value.trim()) {
          return
        }
        dispatch(addTodo(input.value))
        input.value = ''
      }}>
        <input ref={node => {
          input = node
        }} />
        <button type="submit">
          Add Todo
        </button>
      </form>
    </div>
  )
}
AddTodo = connect()(AddTodo)

export default AddTodo
```

# **Storeへ渡す**
全てのContainerコンポーネントはReduxのStoreへのアクセスを必要とするので、それらは購読できます。一つのオプションは全てのContainerコンポーネントへpropとしてそれを渡すことになります。しかしながらそれは`store`をPresentationalコンポーネントでさえ繋がなければならないとして、うんざりします。なぜならコンポーネントツリー野中でContainerが深く描画されることが起こるからです。

我々が推奨するオプションは、[魔法のように](https://facebook.github.io/react/docs/context.html)Storeを明示的に渡すことなしにアプリケーションの全てのContainerコンポーネントへ可能にする`<Provider>`と呼ばれる特別なReact Reduxコンポーネントを使うことです。あなたはルートコンポーネントを描画するときにただ一回それを使う必要があります。

**`index.js`**

```js
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import todoApp from './reducers'
import App from './components/App'

let store = createStore(todoApp)

render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)
```

# **次のステップ**
あなたが得た知識をもっと身につけるために[このチュートリアルの完全なソースコード](http://redux.js.org/docs/basics/ExampleTodoList.html)を読みましょう。それからどのようにネットワークのリクエストとルーティングを処理するかを学ぶために[上級チュートリアル](http://redux.js.org/docs/advanced/)へ直行しましょう。

_翻訳ここまで_

# **終わりに**
~~次のステップの[Example: Todo List](http://redux.js.org/docs/basics/ExampleTodoList.html)はコードだけのステップとなりますので翻訳はこちらで最後となります。~~

今までのコードの構成と次のステップである[Example: Todo List](http://redux.js.org/docs/basics/ExampleTodoList.html)のコードが異なっているのと、コードにコメントがあったほうがわかりやすいので、コメント付き全コードを上げられたら上げようと思います。