Reduxについて / Redux introduction and TODO example with Redux

D1d987836a880f8c29d1f63c88b92f80?s=47 shike
December 22, 2017

Reduxについて / Redux introduction and TODO example with Redux

会社(株式会社Cluex)の社内LT大会にてReduxについて発表しました。
Flux・Reduxの基本概念についてと、Reduxを使ったTODOアプリの紹介をしました。

D1d987836a880f8c29d1f63c88b92f80?s=128

shike

December 22, 2017
Tweet

Transcript

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

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

  3. Fluxとは 3

  4. Flux • Facebookが提唱した単一方向データフローアーキテクチャ http://facebook.github.io/flux/ • 以下の3つが主要な要素 ◦ dispatcher ◦ store

    ◦ view • facebook/fluxはこのアーキテクチャのリファレンス実装 4
  5. Fluxのデータフロー 5 Flux公式ドキュメントより

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

  7. Reduxとは 7

  8. 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
  9. Reduxのデータフロー 9

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

  11. Reduxの特徴 • 状態管理を単一方向フローで行うために Fluxベースで作られたライブラリ • 関数を使うことでシンプルにしている ◦ Redux is true

    to the Flux architecture, but makes it simpler thanks to pure functions. • あくまでやるのは状態管理のみで、副作用が伴う処理はやらない • React以外でも使える 11
  12. Reduxを使ってTODOアプリ 12

  13. View 13

  14. 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 ( <form onSubmit={onSubmit}> <input type="text" ref={input => (this.text = input)} /> <input type="submit" value="Add Todo" /> </form> ); }; AddTodo = connect(null, mapDispatchToProps)(AddTodo); export default AddTodo;
  15. 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 ( <form onSubmit={onSubmit}> <input type="text" ref={input => (this.text = input)} /> <input type="submit" value="Add Todo" /> </form> ); }; AddTodo = connect(null, mapDispatchToProps)(AddTodo); export default AddTodo; propsに渡すaction Componentのpropsにaction が渡される ComponentにReduxの actionをつなぐ actionの呼び出し
  16. Action 16

  17. Action export const addTodo = payload => { return {

    type: ’ADD_TODO’, payload }; }; 17
  18. 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’ } }
  19. Reducer 19

  20. Reducer 20 import { handleActions } from 'redux-actions'; const todos

    = handleActions( { ADD_TODO: (state, action) => { return [ ...state, { text: action.payload.text } ]; } },initialState); export default todos;
  21. 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を生成
  22. 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;
  23. Store 23

  24. 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( <Provider store={store}> <App /> </Provider>, document.getElementById('app') );
  25. 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( <Provider store={store}> <App /> </Provider>, document.getElementById('app') ); reducerを元にstoreを生成
  26. View import { connect } from 'react-redux'; import Todo from

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

    '../components/Todo'; const mapStateToProps = state => { return { todos: state.todos }; }; let TodoList = ({ todos }) => ( <ul> {todos.map((todo, index) => ( <Todo key={index} {...todo} /> ))} </ul> ); TodoList = connect(mapStateToProps)(TodoList); export default TodoList; 27 propsに渡すstate ComponentにReduxの stateを渡す Componentのpropsに stateが渡される
  28. まとめ 28

  29. まとめ 29 • Fluxとはアーキテクチャの名称 • ReduxはFluxに基づいて実装されたライブラリ • Reduxを使うことでReactおよびその他JSアプリでの状態管理がわかりやすく、安全にできる • APIコールなどの副作用が必要になると

    middlewareが別途必要になるので辛そう・・・ • 一気にライブラリがたくさん出てくるので総合的に見ると学習コスト高い
  30. Fin. 30