Slide 1

Slide 1 text

Reduxについて 2017/12/22 Cluex.inc 柴山健吾

Slide 2

Slide 2 text

アジェンダ 1. Fluxとは 2. Reduxとは 3. Reduxを使ってTODOアプリ 2

Slide 3

Slide 3 text

Fluxとは 3

Slide 4

Slide 4 text

Flux ● Facebookが提唱した単一方向データフローアーキテクチャ http://facebook.github.io/flux/ ● 以下の3つが主要な要素 ○ dispatcher ○ store ○ view ● facebook/fluxはこのアーキテクチャのリファレンス実装 4

Slide 5

Slide 5 text

Fluxのデータフロー 5 Flux公式ドキュメントより

Slide 6

Slide 6 text

Fluxの特徴 ● 単一方向のデータバインディング ● dispatcher, store, viewにより責務を適切に分割 6

Slide 7

Slide 7 text

Reduxとは 7

Slide 8

Slide 8 text

Redux ● JSアプリの状態管理のためのライブラリ ○ Redux is a predictable state container for JavaScript apps. ● Fluxアーキテクチャの実装の一つ ● Reduxの三原則 ○ Single source of truth ○ State is read-only ○ Changes are made with pure functions 8

Slide 9

Slide 9 text

Reduxのデータフロー 9

Slide 10

Slide 10 text

Reduxのデータフロー(Side Effectあり) 10

Slide 11

Slide 11 text

Reduxの特徴 ● 状態管理を単一方向フローで行うために Fluxベースで作られたライブラリ ● 関数を使うことでシンプルにしている ○ Redux is true to the Flux architecture, but makes it simpler thanks to pure functions. ● あくまでやるのは状態管理のみで、副作用が伴う処理はやらない ● React以外でも使える 11

Slide 12

Slide 12 text

Reduxを使ってTODOアプリ 12

Slide 13

Slide 13 text

View 13

Slide 14

Slide 14 text

View 14 import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import * as actions from '../actions/actions'; const mapDispatchToProps = dispatch => { return { actions: bindActionCreators(actions, dispatch) }; }; let AddTodo = ({ actions }) => { const onSubmit = e => { e.preventDefault(); actions.addTodo({ text: this.text.value }); this.text.value = ''; }; return ( (this.text = input)} /> ); }; AddTodo = connect(null, mapDispatchToProps)(AddTodo); export default AddTodo;

Slide 15

Slide 15 text

View 15 import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import * as actions from '../actions/actions'; const mapDispatchToProps = dispatch => { return { actions: bindActionCreators(actions, dispatch) }; }; let AddTodo = ({ actions }) => { const onSubmit = e => { e.preventDefault(); actions.addTodo({ text: this.text.value }); this.text.value = ''; }; return ( (this.text = input)} /> ); }; AddTodo = connect(null, mapDispatchToProps)(AddTodo); export default AddTodo; propsに渡すaction Componentのpropsにaction が渡される ComponentにReduxの actionをつなぐ actionの呼び出し

Slide 16

Slide 16 text

Action 16

Slide 17

Slide 17 text

Action export const addTodo = payload => { return { type: ’ADD_TODO’, payload }; }; 17

Slide 18

Slide 18 text

Action export const addTodo = payload => { return { type: ’ADD_TODO’, payload }; }; 18 viewから渡されるデータ { text: ‘Do something’ }のようなObjectが渡される Flux Standard Action × Bad { type: ‘ADD_TODO’, text: ‘Do something’ } ○ Good { type: ‘ADD_TODO’, payload: { text: ‘Do something’ } }

Slide 19

Slide 19 text

Reducer 19

Slide 20

Slide 20 text

Reducer 20 import { handleActions } from 'redux-actions'; const todos = handleActions( { ADD_TODO: (state, action) => { return [ ...state, { text: action.payload.text } ]; } },initialState); export default todos;

Slide 21

Slide 21 text

Reducer 21 import { handleActions } from 'redux-actions'; const todos = handleActions( { ADD_TODO: (state, action) => { return [ ...state, { text: action.payload.text } ]; } },initialState); export default todos; actionのtype 現在のstateとaction 新しいstateを生成

Slide 22

Slide 22 text

Reducer (redux-actionsなし) 22 const todos = (state, action) => { switch (action.type) { case 'ADD_TODO': return [ ...state, { text: action.payload.text } ]; default: return state } } export default todos;

Slide 23

Slide 23 text

Store 23

Slide 24

Slide 24 text

Store 24 import { render } from 'react-dom'; import { Provider } from 'react-redux'; import { createStore } from 'redux'; import todoApp from './reducers'; import App from './App'; let store = createStore(todoApp); render( , document.getElementById('app') );

Slide 25

Slide 25 text

Store 25 import { render } from 'react-dom'; import { Provider } from 'react-redux'; import { createStore } from 'redux'; import todoApp from './reducers'; import App from './App'; let store = createStore(todoApp); render( , document.getElementById('app') ); reducerを元にstoreを生成

Slide 26

Slide 26 text

View import { connect } from 'react-redux'; import Todo from '../components/Todo'; const mapStateToProps = state => { return { todos: state.todos }; }; let TodoList = ({ todos }) => (
    {todos.map((todo, index) => ( ))}
); TodoList = connect(mapStateToProps)(TodoList); export default TodoList; 26

Slide 27

Slide 27 text

View import { connect } from 'react-redux'; import Todo from '../components/Todo'; const mapStateToProps = state => { return { todos: state.todos }; }; let TodoList = ({ todos }) => (
    {todos.map((todo, index) => ( ))}
); TodoList = connect(mapStateToProps)(TodoList); export default TodoList; 27 propsに渡すstate ComponentにReduxの stateを渡す Componentのpropsに stateが渡される

Slide 28

Slide 28 text

まとめ 28

Slide 29

Slide 29 text

まとめ 29 ● Fluxとはアーキテクチャの名称 ● ReduxはFluxに基づいて実装されたライブラリ ● Reduxを使うことでReactおよびその他JSアプリでの状態管理がわかりやすく、安全にできる ● APIコールなどの副作用が必要になると middlewareが別途必要になるので辛そう・・・ ● 一気にライブラリがたくさん出てくるので総合的に見ると学習コスト高い

Slide 30

Slide 30 text

Fin. 30