Redux とは
state(状態)を管理することに特化した、ライブラリです。
React.js を利用していると、コンポーネントに state が含まれ状態の管理が複雑になります。
Reduxでstateを一元管理し、コンポーネントとstateの分離が可能となります。
React.js と合わせて利用することが多いですが、React.js と合わせなくても Redux 単体で利用することが可能です。この記事では、取り扱いません。
前提
- node.js がインストール済みであること
- React.js のコンポーネントを作成できること
- ソースはReduxのexamples/todosなど例が用意されているので、それを見るのがいいです。
環境
記事作成時の環境を記載しています。
項目 | バージョン |
---|---|
node.js | 8.9.4 |
React.js | 16.2.0 |
Redux | 3.7.2 |
react-redux | 5.0.6 |
VSCode | 1.19.2 |
3 つの原則
Single source of truth
The state of your whole application is stored in an object tree within a single store
すべての状態は一つの store(オブジェクト)に格納されます。
- データを一元管理する。
State is read-only
The only way to change the state is to emit an action, an object describing what happened.
状態はアクションを介さないと変更できません。
- 知らないうちに変更されることを防ぐ
Changes are made with pure functions
To specify how the state tree is transformed by actions, you write pure reducers.
reducer 関数で、action を元に state の変更を行います。
- state の変更ではなく、新規 state を返す。
- reducer は分割が可能。
基本
state
store にて一元管理される、アプリケーション全体の状態を表します。
Action (Creator)
actionはイベントが発生した事を表すオブジェクトです。
- 必ず
type
プロパティを含む必要があります。 type
以外の構造は、任意です。
Action Creatorは、Actionを生成を行います。
Reducer
Action を元に、state の変更を行います。
reducerは分割することが可能で、分割した場合はcombineReducers
関数を使用して1つのreducerにまとめて使用します。
Store
action と reducer をまとめ、state を一元管理します。
createStore
関数を使用してstateを作成します。
引数にReducerを渡す必要があります。
データフロー
redux のデータフローは以下の図の様になっております。以下の図は、redux(github)の issue に記載されているものです。
dispatcher は誤りで、dispatch function が正しいですが、データの流れがアニメーションとなっておりわかりやすいと思います。
- view にてイベントが発生
- イベントに対応した、action(データ)を作成し redux に通知
- redux は 受け取った action と store に保持している state を、reducer に渡す
- reducer は受け取った情報(更新前 state/action)をもとに新 state を作成し返却
- store は新 state を view に通知
Reactと連携
ReactとReduxを連携するには、react-redux
パッケージを使用します。
連携するにあたり、Reactのコンポーネントを表現とコンテナを分けて考える必要があります。
表現コンポーネントは、UIに専念します。stateを持つことは可能ですが、状態が一元管理できないので持たせることは少ないと思います。
コンテナ コンポーネントは、Reduxが一元管理しているstateを使用してどのように動くかを定義します。
連携
storeの紐づけ
reduxのexamples/todosから./src/index.js
を抜粋しました。
reduxのcreateStore
で作成したstoreをreact-reduxのProvider
に渡して、ストアを監視できるようになります。
index.js
import React from 'react'
import { render } from 'react-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import App from './components/App'
import reducer from './reducers'
const store = createStore(reducer)
render(
,
document.getElementById('root')
)
コンテナコンポーネント
コンテナコンポーネントは、react-reduxのconnect
関数を使用します。
connect
関数はコンポーネントとstoreを紐づけます。
reduxのexamples/todosの./src/containers
を参照して実装を確認してください。
connect関数の引数
- 第1引数(
mapStateToProps
)
stateからコンポーネントに渡すpropsを生成する関数を指定します。 -
第2引数(
mapDispatchToProps
)
Reduxのstateを更新するには、ReactのsetState
を使用するのではなく、dispatch
関数を使用する必要があります。
この引数では、UIイベントとdispatch
関数の対応を定義します。
connect
関数の戻り値の関数に対して、上記内容を含むpropsを渡したいコンポーネントを指定する事で、storeの内容が表現コンポーネントと紐づき表現コンポーネントの表示および動きが変わります。
参照
ECMAScript,Javaを扱います。
最近は、vue.jsなどフロントエンドの技術に興味あり!
中日ドラゴンズを応援してます。
コメント