Redux


「戸Redux」とは?


ReduxはJavaScriptアプリケーションの予測可能な状態コンテナです.
Reduxは一貫性があり、異なる環境(サーバ、クライアント、ネイティブ)で実行されます.
テストしやすいアプリケーションの作成に役立ちます.さらに、タイムトラベルデバッガと組み合わせたリアルタイムコードの変更など、優れた開発者体験を提供します.

🖍基本例

import { createStore } from 'redux'

/**
 * 이것이 (state, action) => state 형태의 순수 함수인 리듀서입니다.
 * 리듀서는 액션이 어떻게 상태를 다음 상태로 변경하는지 서술합니다.
 *
 * 상태의 모양은 당신 마음대로입니다: 기본형(primitive)일수도, 배열일수도, 객체일수도,
 * 심지어 Immutable.js 자료구조일수도 있습니다.  오직 중요한 점은 상태 객체를 변경해서는 안되며,
 * 상태가 바뀐다면 새로운 객체를 반환해야 한다는 것입니다.
 *
 * 이 예제에서 우리는 `switch` 구문과 문자열을 썼지만,
 * 여러분의 프로젝트에 맞게
 * (함수 맵 같은) 다른 컨벤션을 따르셔도 좋습니다.
 */
function counter(state = 0, action) {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}

// 앱의 상태를 보관하는 Redux 저장소를 만듭니다.
// API로는 { subscribe, dispatch, getState }가 있습니다.
let store = createStore(counter)

// subscribe()를 이용해 상태 변화에 따라 UI가 변경되게 할 수 있습니다.
// 보통은 subscribe()를 직접 사용하기보다는 뷰 바인딩 라이브러리(예를 들어 React Redux)를 사용합니다.
// 하지만 현재 상태를 localStorage에 영속적으로 저장할 때도 편리합니다.

store.subscribe(() => console.log(store.getState())))

// 내부 상태를 변경하는 유일한 방법은 액션을 보내는 것뿐입니다.
// 액션은 직렬화할수도, 로깅할수도, 저장할수도 있으며 나중에 재실행할수도 있습니다.
store.dispatch({ type: 'INCREMENT' })
// 1
store.dispatch({ type: 'INCREMENT' })
// 2
store.dispatch({ type: 'DECREMENT' })
// 1
ステータスを直接変更するのではなく、アクションと呼ばれる通常のオブジェクトで発生する変更を指定します.次に、アプリケーション全体のステータスを変更する方法を決定する特殊な関数を作成します.
通常、Reduxアプリケーションにはroot reducer関数を持つリポジトリが1つしかありません.アプリケーションの増大に応じて、ルートコントローラをステータスツリーの異なる部分でそれぞれ操作する小さなアクチュエータに分けることができます.1つのルート構成部品からreactアプリケーションを複数の小構成部品の組合せに置き換えるのと同じです.

Redux pattern



≪アクション|Actions|emdw≫:アクションは、アプリケーションがリポジトリに送信するデータのセットです.リポジトリ内の唯一の情報源になります.友達はstoredispatch()で送信できます.
動作は通常のJavaScriptオブジェクトです.アクションには、どのタイプのアクションが実行されるかを示すタイプのプロパティが必要です.タイプは通常、文字列定数として定義されます.アプリケーションが十分大きい場合は、これらのタイプを個別のモジュールに分離することもできます.
const ADD_TODO = 'ADD_TODO'

{
  type: ADD_TODO,
  text: 'Build my first Redux app'
}

import { ADD_TODO, REMOVE_TODO } from '../actionTypes'
Reducer(Reducer):動作は何が起こったかを記述しますが、アプリケーションの状態がどのように変化したかは分かりません.これは李杜瑟がしなければならないことだ.
import { VisibilityFilters } from './actions'

const initialState = {
  visibilityFilter: VisibilityFilters.SHOW_ALL,
  todos: []
}
function todoApp(state = initialState, action) {
  switch (action.type) {
    case SET_VISIBILITY_FILTER:
      return Object.assign({}, state, {
        visibilityFilter: action.filter
      })
    default:
      return state
  }
}
リポジトリ(Store):前節では、「何が起こるか」を示すアクションと、これらのアクションに基づいてステータスを変更するデモプログラムを定義しました.
リポジトリは、それらを一緒にインポートするオブジェクトです.リポジトリでは、次の操作を実行する必要があります.
アプリケーションのステータスを保存します.
getState()でステータスにアクセスします.
ステータスをdispatch(action)で変更できます.
subscribe(listener)でリスナーを登録します.
Reduserを作成すると、リポジトリの作成が容易になります.前節では,Reducers()を組み合わせて複数のReducerを1つに統合した.私たちはそれをcreateStore()に渡します.
import { createStore } from 'redux'
import todoApp from './reducers'

let store = createStore(todoApp)
初期状態をcreateStore()の2番目の引数として指定することもできます.これは、サーバ上で実行されているReduxアプリケーションのステータスに一致するようにクライアントのステータスを入力するのに役立ちます.
let store = createStore(todoApp, window.STATE_FROM_SERVER)
import { createStore } from 'redux'
import todoApp from './reducers'

let store = createStore(todoApp)

Reduxデータストリーム


友達のこのstoredispatch(action)を呼び出します.
```js
{ type: 'LIKE_ARTICLE', articleId: 42 };
{ type: 'FETCH_USER_SUCCESS', response: { id: 3, name: 'Megan' } };
{ type: 'ADD_TODO', text: 'Read the Redux docs.'};
2.Reduxリポジトリは、指定したReduser関数を呼び出します.
```js
// 애플리케이션의 현재 상태(할일 목록과 선택된 필터)
let previousState = {
  visibleTodoFilter: 'SHOW_ALL',
  todos: [{
    text: 'Read the docs.',
    complete: false
  }]
};

// 실행되는 액션(할일 추가)
let action = {
  type: 'ADD_TODO',
  text: 'Understand the flow.'
};

// 리듀서가 다음 상태를 반환함
let nextState = todoApp(previousState, action);


리듀서는 단지 다음 상태를 **계산**하는 순수 함수라는 점을 기억하세요. 리듀서는 완전히 예측 가능해야 합니다: 같은 입력을 가지고 몇번을 호출하든지 같은 출력이 나와야 합니다. API 호출이나 라우터 전환같은 사이드이펙트를 일으켜서는 안됩니다. 이런 일들은 액션이 전달되기 전에 행해져야 합니다.
3.各スーパーユーザーの出力を1つのステータスツリーにマージします.
RootReduserの構成方法は、お客様次第です.ReduxはReducer()helper関数を組み合わせて提供し、ルートディレクトリコントローラをステータスツリーの各枝を処理する関数に分けることができます.
Reducers()を組み合わせる方法は次のとおりです.みんなに2人の隊長がいると思ってください.1つは保留中のリストで、もう1つは選択したフィルタ設定です.
```js
function todos(state = [], action) {
  // Somehow calculate it...
  return nextState;
}

function visibleTodoFilter(state = 'SHOW_ALL', action) {
  // Somehow calculate it...
  return nextState;
}

let todoApp = combineReducers({
  todos,
  visibleTodoFilter
});
アクションを送信すると、コンビネーションモニタが返すtodoAppで2つのモニタが呼び出されます.
```js
let nextTodos = todos(state.todos, action);
let nextVisibleTodoFilter = visibleTodoFilter(state.visibleTodoFilter, action);
2つの結果を1つのステータスツリーにマージします.
```js
return {
  todos: nextTodos,
  visibleTodoFilter: nextVisibleTodoFilter
};
4.Reduxリポジトリは、スーパーユーザーによって返されたステータスツリーを保存します.
この新しい木はみんなのアプリケーションの次の状態です!store.subscribe(listener)に登録されているすべてのリスナーがロードされ、現在のステータスを取得するために格納されます.getState()が呼び出されます.
UIは新しい状態に応じて変更されます.皆さんがReact Reduxでバインドされているならこの時点はcomponentですsetState(newState)を呼び出します.