Table of Contents
Introduction
基本概念
Redux は以下の3で成り立つ。
State
state
はセッターのないモデルのようなもの。
Action
action
を使用する事のみでstate
の内容を変更できる。
action
はただの JavaScript のオブジェクト。
Reducer
reducer
はaction
とstate
を結びつけるもの。
reducer
はstate
action
を引数に取り、次のstate
の状態を返す単なるファンクション。
3 つの原則
Single source of truth
アプリのすべてのstate
は1つのstore
に集約する。
State is read-only
state
は単純なオブジェクトであるaction
を使用してのみでしか変更を行わない。
Changes are made with pure functions
reducer
は純粋なファンクションであり、与えられた値を変更するのではなく、必ず新しい値を返す。
Basics
Actions
action
は、アプリケーションからstore
にデータを送信する情報のペイロードです。store.dispatch()
でstore
に送ることが可能。
todo にアイテムを加えるアクションの例
{
type: ADD_TODO
text: 'Build my first Redux app'
}
actions
は JS の単純なオブジェクトで,必ず使用されるaction
を示すtype
プロパティをもつ。
Action Creators
Action Creators
はその名の通り、action
を作り出す関数である。
Redux ではAction Creators
はaction
オブジェクトを返す。
function addTodo(text) {
return {
type: ADD_TODO,
text
}
}
その他の actionsCreators と VisibilityFilters
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 }
}
export const VisibilityFilters = {
SHOW_ALL: 'SHOW_ALL',
SHOW_COMPLETED: 'SHOW_COMPLETED',
SHOW_ACTIVE: 'SHOW_ACTIVE'
}
Reducers
Reducers 基本
Reducers
はstore
に送られたaction
に応じてstate
がどのように変更するのかを示す。
reducer
はstate
action
を引数に取り、次のstate
の状態を返す単なるファンクション。
(previousState, action) => newState
state
の構造の例
- The currently selected visibility filter
- The actual list of todos.
{
visibilityFilter: 'SHOW_ALL',
todos: [
{
text: 'Consider using Redux',
completed: true
},
{
text: 'Keep all state in a single tree',
completed: false
}
]
}
Reducer
が純粋は関数であることは重要であり、下記の事はしてはならない。
- Mutate its arguments.
- Perform side effects like API calls and routing transitions.
- Call non-pure functions(e.g. Date.now() or Math.random().)
Reducer
を作成する
最初の state
を作成し、reducer
に与える。
引数の値は変更せずにobject.assign(target, ...sources)
を利用する事でコピーを作成し、新しいオブジェクトを返すようにする。または2つ目の例のようにObject Spread Operatorを使用する事で同様の事を行える。
default
では元のstate
を返すように設定する事で、不明なaction
に対しては元の状態を返す。
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.fiter
})
default:
return state
}
}
//上の関数と同様だがObject Spread Operatorを使用
function todoApp(state = initialState, action) {
switch(action.type) {
case SET_VISIBILITY_FILTER:
return {
...state,
visibilityFilter: action.filter
}
default:
return state
}
}
やってることとしては以下のように...state
で開いて中身の値に新しい要素を加えて新しい値として返してるだけ。
const initialState = {
todos: [1,2,3]
}
console.log(...initialState.todos, 4)
更に actions を付け加える
function todoApp(state = initialState, action) {
switch(action.type){
case SET_VISIBILITY_FLITER:
return {
...state,
visibilityFilter: action.filter
}
case ADD_TODO:
return {
...state.todos,
{
text: action.text,
completed: false
}
}
default:
return state
}
}
Store
store
は以下の為に存在する。
- Holds application state;
- Allows access to state via
getState()
; - Allows state to be updated via
dispatch(action)
; - Registers listeners via
subscribe(listener)
; - Handles unregistering of listeners via the function returned by
subscribe(listener)
1 つの Redux アプリに関して 1 つのstore
だけが存在する。 様々なデータを扱う際にはreducer
を細分化する事で対応する。
reducer
があればのstore
の作成は簡単で、以下のようにできる。
import { createStore } from 'redux'
import todoApp from './reducers'
const store = createStore(todoApp)
アクションを送る。
以下のようにアプリのstate
の値を獲得したり、変更したりできる。
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()
Usage with React
Installing React-Redux
以下のように react-redux
をインストールする。
$ npm install --save react-redux
Presentational and Container Componensts
React
は view を扱うライブラリでありRedux
が有するstore
やAction
の情報と疎結合になっていることが好ましい。
Container Components
Redux
のstore
やAction
を受け取りReact
コンポーネントのProps
として渡す役割を担う。(= React と Redux の橋渡し。JSX は使用しない。)
Presentational Components
Redux
依存のない純粋な React コンポーネント。