Redux入門 (React.js)


React.jsでアプリケーションを開発するときに使われる「Redux」の入門記事です。

🐡 Reduxとは

React.jsが扱うUIのstate(状態)を管理するためのフレームワークです。React.jsで複雑なアプリケーションを作るとstateの変更箇所が複数に分散(componetが複数箇所で保持)して、管理が困難になるのを解決するためです。

🍮 Reduxの要素

Action

  • Actionは「何をする」という情報をもつオブジェクトです
  • Actionstore.dispatch()で store を変更する Reducer へ送られます
  • 文字列のtypeプロパティを必ず持ちます
const ADD_TODO = 'ADD_TODO'
{
type: ADD_TODO,
text: 'Input user message 1'
}

ActionCreator

ActionCreatorActionを生成するメソッドです。

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

dispatchするときはActionCreatorで作成したactionを渡します。

dispatch(addTodo(text))

もしくは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

  • ReducerActionstateから「新しいstate」を返すメソッドです
  • Actiontypeプロパティに応じて処理を書く必要があります
  • 生成された「新しい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は現在のstateactionを受けて新しいstateを返すだけの純粋なメソッドとします
  • 引数の値を変更したり、APIを呼び出すような副作用が発生すること、毎回値が変わることはNG

🗻 よく使うAPI

Provider

Providerの目的は次の2つです。

  • Reactコンポーネント内でreact-reduxのconnectを使えるようにすること
  • ラップしたコンポーネントにstore情報を渡すこと

connect

ReduxのStoreがReactにアクセスするための関数。

サンプルコード

// index.js
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')
);
// App.js
import React, { Component } from 'react';
import { connect } from 'react-redux';

class App extends Component {
doSomething(e) {
// do something
}

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のヘビーユーザーになので、「ここ」から会員登録してもらえるとサービス開発が捗ります!

📚 おすすめの書籍