【定期更新】Redux公式チュートリアルのざっくりした和訳と流れ

気が向いたときに更新していきます。
Redux Toolkit公式チュートリアル、Redux公式チュートリアルをかいつまんでざっくりと翻訳したものです。
「」内は、進めるにあたっての自分の思考の流れを思い出すためにメモしているものです。
誤りが多いかもしれませんが大目にみてください。

https://redux-toolkit.js.org/tutorials/basic-tutorial
>This tutorial assumes that you are already familiar with the concepts of the core Redux library, as well as how to use it with React. If you aren't, please take some time to read through the Redux docs and React-Redux docs first, as the explanations here focus on how RTK usage differs from "typical" Redux code.

「Reduxを先にやれってことか。」

# Redux

## Installation
https://redux.js.org/introduction/installation

>Create a React Redux App
The recommended way to start new apps with React and Redux is by using the official Redux+JS template for Create React App, which takes advantage of Redux Toolkit and React Redux's integration with React components.

「オススメらしいからこのやり方でやろ。」

```
$ mkdir ReduxTutorial
$ cd ReduxTutorial
$ npx create-react-app my-app --template redux
```

## Actioins
https://redux.js.org/basics/actions

>Actions are payloads of information that send data from your application to your store. They are the only source of information for the store. You send them to the store using store.dispatch().

>**Action**は、アプリケーションから**store**にデータを送信する情報のペイロードです。 それらは**store**の唯一の情報源です。 それらは、``store.dispatch（）``を使用して**store**に送信します。

>(補足)
ペイロード
①乗客・貨物などの有料荷重。
②航空機やミサイルの有効搭載量、搭載物。
③ロケットの打ち上げの性能を示す指標の一。所定の高度に打ち上げることのできる人工衛星の重量。
④人件費。

「**Action**は、**store**に送られる唯一無二の存在なんやな〜。 ``store.dispatch（）``はよくわからんからほっとこ。」

>Actions are plain JavaScript objects. Actions must have a type property that indicates the type of action being performed. Types should typically be defined as string constants. 

>**Action**は単純なJavaScriptオブジェクトです。 **Action**には、実行されるアクションのタイプを示すtypeプロパティが必要です。 typeは通常、文字列定数として定義する必要があります。

```javascript
const ADD_TODO = 'ADD_TODO'
{
  type: ADD_TODO,
  text: 'Build my first Redux app'
}
```

「**Action**の実態は、このオブジェクトひとまとまりのことみたい。``type``は定数で定義するみたいやなー。オブジェクトの中のtextはよくわからんけどほっとこ。」

### Action Creators

>Action creators are exactly that—functions that create actions. It's easy to conflate the terms “action” and “action creator”, so do your best to use the proper term.
In Redux, action creators simply return an action:

>**Action creators**は、まさにそれ、つまり**Action**を作成する関数です。 「アクション」と「アクションクリエーター」という用語を混同するのは簡単なので、適切な用語を使用するように最善を尽くしてください。Reduxでは、**Action creators**は単に**Action**を返します。

```javascript
function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}
```

「**Action creators**は、``addTodo関数``自体をさしてて、**Action**、つまり、オブジェクトひとまとまりを返すんやなー。」

「さっきのよく分からんかったtextが引数で渡ってきてるから、多分、追加したいTODOを**Action creators**、つまり、``addTodo関数``に渡すんやろうなー。」

「``text`` は、 ``text: text``の省略ってことも覚えとかな混乱しそうやな。。。」

### Source Code

```action.js
/*
 * action types
 */

export const ADD_TODO = 'ADD_TODO'
export const TOGGLE_TODO = 'TOGGLE_TODO'
export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER'

/*
 * other constants
 */

export const VisibilityFilters = {
  SHOW_ALL: 'SHOW_ALL',
  SHOW_COMPLETED: 'SHOW_COMPLETED',
  SHOW_ACTIVE: 'SHOW_ACTIVE'
}

/*
 * action creators
 */

export function addTodo(text) {
  return { type: ADD_TODO, text }
}

export function toggleTodo(index) {
  return { type: TOGGLE_TODO, index }
}

export function setVisibilityFilter(filter) {
  return { type: SET_VISIBILITY_FILTER, filter }
}
```

「``other constants`` はあとで使うっぽいな」

## Reducers
https://redux.js.org/basics/reducers

>**Reducers**は、**store**に送信された**Action**に応じてアプリケーションの状態がどのように変化するかを指定します。 **Action**は何が起こったかを説明するだけで、アプリケーションの状態がどのように変化するかを説明しないことに注意してください。

「 **Action**はただのオブジェクトの塊として**store**に送信されるんやな。だから、**Reducers**による指示が必要になるんか。」

### Designing the State Shape

```js
{
  visibilityFilter: 'SHOW_ALL',
  todos: [
    {
      text: 'Consider using Redux',
      completed: true
    },
    {
      text: 'Keep all state in a single tree',
      completed: false
    }
  ]
}
```

「これから**state**が出てきたら、実態はこんな形のオブジェクトってことをイメージしたらわかりやすいかもな。」

>We'll start by specifying the initial state. Redux will call our reducer with an undefined state for the first time. This is our chance to return the initial state of our app:

>最初に、初期状態を指定します。 Reduxは初めて、未定義の状態で**Reducers**を呼び出します。 これは、アプリの初期状態を返す機会です。

```js
import { VisibilityFilters } from './actions'

const initialState = {
  visibilityFilter: VisibilityFilters.SHOW_ALL,
  todos: []
}

function todoApp(state, action) {
  if (typeof state === 'undefined') {
    return initialState
  }

  // For now, don't handle any actions
  // and just return the state given to us.
  return state
}
```

「さっきよく分からんかった``actions.js``の``VisibilityFilters``が使われてるな。 初期状態は『全部見せる』に設定してある。」
「**Reducers** は ``todoApp``関数のことみたいやな。状態(state)と**Action**を引数で受け取ってるな。状態(state)がなかったら初期状態を返すみたいや。」

### Handling Actions

>状態オブジェクトの外観を決定したので、そのための**Reducers**を作成する準備ができました。 **Reducers**は、前の状態と**Action**を取り、次の状態を返す純粋な関数です。

「状態(state)があったら、新しい状態(state)を返すってことやな。」

```javascript
import {
  SET_VISIBILITY_FILTER,
  VisibilityFilters
} from './actions'

...

function todoApp(state = initialState, action) {
  switch (action.type) {
    case SET_VISIBILITY_FILTER:
      return Object.assign({}, state, {
        visibilityFilter: action.filter
      })
    default:
      return state
  }
}
```

「importしてる``SET_VISIBILITY_FILTER``は、確か**Action**の``type``のうちの一つやったな。」

「受け取った**Action**の``type``が``SET_VISIBILITY_FILTER``だったら。。。っていう処理の流れなんか。　Actionを受け取るイメージがまだあんまりわかないけどほっとこ。」

「``Object.assign()``は[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)によると、オブジェクトを合体させるらしい。 initialStateみたいな{visibilityFilter: 〇〇, todos: [〇〇]} の形になるってことやな。」

「``action.filter`` の``filter``は、**Action creators**の``setVisibilityFilter`` 関数の引数やったな。。。 実態はまだ分からんな。」


### Handling More Actions

```js
import {
  ADD_TODO,
  TOGGLE_TODO,
  SET_VISIBILITY_FILTER,
  VisibilityFilters
} from './actions'

...

function todoApp(state = initialState, action) {
  switch (action.type) {
    case SET_VISIBILITY_FILTER:
      return Object.assign({}, state, {
        visibilityFilter: action.filter
      })
    case ADD_TODO:
      return Object.assign({}, state, {
        todos: [
          ...state.todos,
          {
            text: action.text,
            completed: false
          }
        ]
      })
    default:
      return state
  }
}
```

「渡ってきた**Action**の``type``が``ADD_TODO``やったら、状態(state)に、``text``と``completed``の情報が足された状態(state)を返すんやなー。」

```js
case TOGGLE_TODO:
  return Object.assign({}, state, {
    todos: state.todos.map((todo, index) => {
      if (index === action.index) {
        return Object.assign({}, todo, {
          completed: !todo.completed
        })
      }
      return todo
    })
  })
```

「渡ってきた**Action**の``type``が``TOGGLE_TODO``やったら、状態(state)の``todo``を一つづつ調べて、渡ってきた**Action**の``index``と一致した``todo``の``completed``の状態を変えた状態(state)を返すんやなー。」

### Splitting Reducers

```js
function todoApp(state = initialState, action) {
  switch (action.type) {
    case SET_VISIBILITY_FILTER:
      return Object.assign({}, state, {
        visibilityFilter: action.filter
      })
    case ADD_TODO:
      return Object.assign({}, state, {
        todos: [
          ...state.todos,
          {
            text: action.text,
            completed: false
          }
        ]
      })
    case TOGGLE_TODO:
      return Object.assign({}, state, {
        todos: state.todos.map((todo, index) => {
          if (index === action.index) {
            return Object.assign({}, todo, {
              completed: !todo.completed
            })
          }
          return todo
        })
      })
    default:
      return state
  }
}
```
「今までの**Reducer**はこんな感じやな。」

>理解しやすくする方法はありますか？ ``todos``と``visibilityFilter``は完全に独立して更新されるようです。 時々、状態フィールドは互いに依存し、より多くの考慮が必要ですが、私たちの場合、更新タスクを別の関数に簡単に分割できます：

「確かに。``case SET_VISIBILITY_FILTER``の時だけ``todos``を更新せず、``visibilityFilter``の値を変えるっていう、違う仕事をしてる。」

```js
function todos(state = [], action) {
  switch (action.type) {
    case ADD_TODO:
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    case TOGGLE_TODO:
      return state.map((todo, index) => {
        if (index === action.index) {
          return Object.assign({}, todo, {
            completed: !todo.completed
          })
        }
        return todo
      })
    default:
      return state
  }
}

function todoApp(state = initialState, action) {
  switch (action.type) {
    case SET_VISIBILITY_FILTER:
      return Object.assign({}, state, {
        visibilityFilter: action.filter
      })
    case ADD_TODO:
      return Object.assign({}, state, {
        todos: todos(state.todos, action)
      })
    case TOGGLE_TODO:
      return Object.assign({}, state, {
        todos: todos(state.todos, action)
      })
    default:
      return state
  }
}
```

>``todo``は``state``も受け入れますが、状態は配列です。 これで、``todoApp``は``todos``に管理する状態のスライスのみを提供し、``todos``はそのスライスだけを更新する方法を知っています。 これは**reducer compositionと呼ばれ、Reduxアプリを構築する基本的なパターンです**。

「``todoApp``関数は、``todo``関数に、**Action**に応じて``todo``を変更してやーって感じで投げてるのか。」
「``todo``関数は、``visibilityFilter``に対しては我関せずって感じになったな。」

>**Reducer**の構成についてさらに詳しく見てみましょう。 また、``visibilityFilter``のみを管理する**Reducer**を抽出できますか？ 私たちはできる。
インポートの下で、ES6 Object Destructuringを使用して``SHOW_ALL``を宣言しましょう。

```js
const { SHOW_ALL } = VisibilityFilters
```

```js
function visibilityFilter(state = SHOW_ALL, action) {
  switch (action.type) {
    case SET_VISIBILITY_FILTER:
      return action.filter
    default:
      return state
  }
}
```

「``visibilityFilter``関数は、``todo``に対しては我関せずって感じになったな。」

>これで、メインの**Reducer**を、**state**の一部を管理する**Reducer**を呼び出し、それらを単一のオブジェクトに結合する関数として書き換えることができます。 また、完全な初期状態を知る必要もありません。 子**Reducer**は、最初は未定義の場合、初期状態を返すだけで十分です。

```js
function todos(state = [], action) {
  switch (action.type) {
    case ADD_TODO:
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    case TOGGLE_TODO:
      return state.map((todo, index) => {
        if (index === action.index) {
          return Object.assign({}, todo, {
            completed: !todo.completed
          })
        }
        return todo
      })
    default:
      return state
  }
}

function visibilityFilter(state = SHOW_ALL, action) {
  switch (action.type) {
    case SET_VISIBILITY_FILTER:
      return action.filter
    default:
      return state
  }
}

function todoApp(state = {}, action) {
  return {
    visibilityFilter: visibilityFilter(state.visibilityFilter, action),
    todos: todos(state.todos, action)
  }
}
```

「スッキリしたな。``todoApp``関数は、ちゃんと前みた``Designing the State Shape``のような**state**を返しているな。」

>これらの**Reducer**のそれぞれがグローバル**state**の独自の部分を管理していることに注意してください。 状態パラメーターは**Reducer**ごとに異なり、管理する状態の一部に対応します。
これはすでに見栄えが良いです！ アプリが大きい場合、**Reducer**を個別のファイルに分割し、それらを完全に独立させて、異なるデータドメインを管理できます。

>最後に、Reduxは、上記の``todoApp``が現在行っているのと同じボイラープレートロジックを実行する``CombineReducers（）``と呼ばれるユーティリティを提供します。 その助けを借りて、``todoApp``を次のように書き換えることができます。

```js
import { combineReducers } from 'redux'

const todoApp = combineReducers({
  visibilityFilter,
  todos
})

export default todoApp
```
>このコードは下と同等です。

```js
export default function todoApp(state = {}, action) {
  return {
    visibilityFilter: visibilityFilter(state.visibilityFilter, action),
    todos: todos(state.todos, action)
  }
}
```

「``combineReducers``の実態はこれだったのか！！(感動)」

### Source Code

```reducers.js
import { combineReducers } from 'redux'
import {
  ADD_TODO,
  TOGGLE_TODO,
  SET_VISIBILITY_FILTER,
  VisibilityFilters
} from './actions'
const { SHOW_ALL } = VisibilityFilters

function visibilityFilter(state = SHOW_ALL, action) {
  switch (action.type) {
    case SET_VISIBILITY_FILTER:
      return action.filter
    default:
      return state
  }
}

function todos(state = [], action) {
  switch (action.type) {
    case ADD_TODO:
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    case TOGGLE_TODO:
      return state.map((todo, index) => {
        if (index === action.index) {
          return Object.assign({}, todo, {
            completed: !todo.completed
          })
        }
        return todo
      })
    default:
      return state
  }
}

const todoApp = combineReducers({
  visibilityFilter,
  todos
})

export default todoApp
```

## Store
https://redux.js.org/basics/store

>前のセクションでは、「起こったこと」に関する事実を表す**Action**と、それらの**Action**に従って**state**を更新する**Reducer**を定義しました。

>**Store**は、それらをまとめるオブジェクトです。 **Store**には以下の責任があります。
・アプリケーションの**state**を保持します。
・``getState（）``を介して**state**にアクセスできます。
・``dispatch（action）``を介して**state**を更新できるようにします。
・``subscribe（listener）``を介してリスナーを登録します。
・``subscribe（listener）``によって返される関数を介してリスナーの登録解除を処理します。
Reduxアプリケーションにはストアが1つしかないことに注意してください。 データ処理ロジックを分割する場合は、多くのストアの代わりにリデューサー構成を使用します。

>**Reducer**があれば、簡単に**Store**を作成できます。 前のセクションでは、``combineReducers（）``を使用して複数の**Reducer**を1つに結合しました。 これをインポートして、``createStore（）``に渡します。

```js
import { createStore } from 'redux'
import todoApp from './reducers'
const store = createStore(todoApp)
```

### Dispatching Actions

```js
import {
  addTodo,
  toggleTodo,
  setVisibilityFilter,
  VisibilityFilters
} from './actions'

// Log the initial state
console.log(store.getState())

// Every time the state changes, log it
// Note that subscribe() returns a function for unregistering the listener
const unsubscribe = store.subscribe(() => console.log(store.getState()))

// Dispatch some actions
store.dispatch(addTodo('Learn about actions'))
store.dispatch(addTodo('Learn about reducers'))
store.dispatch(addTodo('Learn about store'))
store.dispatch(toggleTodo(0))
store.dispatch(toggleTodo(1))
store.dispatch(setVisibilityFilter(VisibilityFilters.SHOW_COMPLETED))

// Stop listening to state updates
unsubscribe()
```

>これにより、**Store**が保持する**state**がどのように変化するかを確認できます。

<img width="645" alt="スクリーンショット 2020-07-12 18.14.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/2100e9de-c75b-32c3-7484-7c35dc1fcbcc.png">


「
>**Action**は、アプリケーションから**store**にデータを送信する情報のペイロードです。 それらは**store**の唯一の情報源です。 それらは、``store.dispatch（）``を使用して**store**に送信します。

ってこのことやったんやなー。
引数の``addTodo``関数、すなわち、``action creator``によって**Action**が渡されてるんや。」
「**Action**が渡された**store**の中で**Reducer**が動いてるイメージやな。」