React.jsでアプリケーションを開発するときに使われる「Redux」の入門記事です。
🎂 Reduxとは
React.jsが扱うUIのstate(状態)を管理するためのフレームワークです。React.jsで複雑なアプリケーションを作るとstateの変更箇所が複数に分散(componetが複数箇所で保持)して、管理が困難になるのを解決するためです。
🐝 Reduxの要素
Action
Action
は「何をする」という情報をもつオブジェクトです
Action
はstore.dispatch()
で store を変更する Reducer へ送られます
- 文字列の
type
プロパティを必ず持ちます
const ADD_TODO = 'ADD_TODO' { type: ADD_TODO, text: 'Input user message 1' }
|
ActionCreator
ActionCreator
はAction
を生成するメソッドです。
function addTodo(text) { return { type: ADD_TODO, text } }
|
dispatch
するときはActionCreator
で作成したaction
を渡します。
もしくはdispatch
までを行うActionCreator
を準備する方法もあります。
const boundAddTodo = (text) => dispatch(addTodo(text)); const boundCompleteTodo = (index) => dispatch(completeTodo(index));
|
reduxのbindActionCreators()
を使う方法もあるようです。
import { Component } from 'react' import { bindActionCreators } from 'redux' import { connect } from 'react-redux'
let boundActionCreators = bindActionCreators(TodoActionCreators, dispatch)
|
同期・非同期の ActionCreator をつくるTipsを別記事に書きました。
Redux で同期、非同期 API 通信を行う
Store
Store
はアプリケーションの状態(state)を保持する場所です。Store
の役割は次のとおりです。
- stateを保持する
getState()
メソッドでstateにアクセスを許可する
dispatch(action)
メソッドでstateを更新する
subscribe(listener)
メソッドでリスナーを登録できる
todo
のサンプルのstateは次のようになります。
{ visibilityFilter: 'SHOW_ALL', todos: [ { text: 'Input user message 1', completed: false, }, { text: 'Past user message 0', completed: false, }, ] }
|
Store
には次のルールがあります。
- アプリケーション内で
Store
は1つのみとし、State
は単独のオブジェクトとしてStoreに保持する必要があります
state
を直接変更することはせず、Store
へdispatchすることでしかstate
は変更できません
Reducer
Reducer
はAction
とstate
から「新しいstate
」を返すメソッドです
Action
のtype
プロパティに応じて処理を書く必要があります
- 生成された「新しい
state
」はstore
に保持されます
state
にはUIの内容を入れないようにするのが推奨されます
function todos(state = [], action) { switch (action.type) { case ADD_TODO: return [ ...state, { text: action.text, completed: false } ] case COMPLETE_TODO: return [ ...state.slice(0, action.index), Object.assign({}, state[action.index], { completed: true }), ...state.slice(action.index + 1) ] 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) } }
|
Reducer
には次のルールがあります。
Reducer
は現在のstate
とaction
を受けて新しいstate
を返すだけの純粋なメソッドとします
- 引数の値を変更したり、APIを呼び出すような副作用が発生すること、毎回値が変わることはNG
🎳 よく使うAPI
Provider
Providerの目的は次の2つです。
- Reactコンポーネント内でreact-reduxの
connect
を使えるようにすること
- ラップしたコンポーネントにstore情報を渡すこと
connect
ReduxのStoreがReactにアクセスするための関数。
サンプルコード
import React from 'react'; import ReactDOM from 'react-dom'; import { createStore, combineReducers } from "redux"; import { Provider } from "react-redux"; import App from './App';
ReactDOM.render( </Provider>, document.getElementById('root') );
|
import React, { Component } from 'react'; import { connect } from 'react-redux';
class App extends Component { doSomething(e) { }
render() { const { app: { count } } = this.props; return ( "App" > "App-header" > Welcome to React</h2> div> "App-intro" > To get started, edit src/App.js and save to reload. .doSomething}>hoge</button> div> ); } }
function mapStateToProps(state) { return { app: state.app }; }
export default connect(mapStateToProps)(App);
|
🐞 参考リンク
🖥 VULTRおすすめ
「VULTR」はVPSサーバのサービスです。日本にリージョンがあり、最安は512MBで2.5ドル/月($0.004/時間)で借りることができます。4GBメモリでも月20ドルです。
最近はVULTRのヘビーユーザーになので、「ここ」から会員登録してもらえるとサービス開発が捗ります!