Reduxについて
-
Upload
yuusuke-takeuchi -
Category
Technology
-
view
2.288 -
download
0
Transcript of Reduxについて
Reduxについて
年末JavaScript祭ゆく年くる年 in IDCフロンティア
2015/12/26 竹内 佑介
自己紹介竹内 佑介
プログラマーやってます
最近Reduxばっかやったので、そろそろ別のことをやりたいです
今期の嫁はチノちゃんです
大規模javascript案件でこんなこと困ってませんか
View、イベントハンドラ、 ロジックが入り乱れて カオスコードに
ロジックが特定のDom構造を 前提にしているため
再利用&メンテナンス不可能
その課題、Reduxなら 解決できるかも
Reduxとは?
fluxパターンを実装した、フレームワークの一種
ReduxはView以外を提供している
http://redux.js.org/ ここを提供する
fluxの基本的な考え方
描画の元となる
pureオブジェクトstoreを元にDomを
描画する
fluxの基本的な考え方
viewまたは
AJAX通信がアクションを発行
アクションに応じてStoreを変更する
Reduxの基本StoreState(基本となるデータいわゆるModel)を持つ
ActionCreator(fluxだとAction)イベント発行、サーバとの通信
Reducer(fluxだとDispatcher)
Actionに応じてStateを更新
コードを見てイメージを掴みましょう
コード例 Action Creatorfunction addTodo(text) { return { type: ADD_TODO, text } }
アクション用オブジェクトを変えす関数を書く
返すオブジェクトは上記パターンでなくてもOK
非同期アクションは次で説明
コード例 Action Creator(非同期)export const REQUEST_POSTS = 'REQUEST_POSTS' function requestPosts(reddit) { return { type: REQUEST_POSTS, reddit } }
export const RECEIVE_POSTS = 'RECEIVE_POSTS' function receivePosts(reddit, json) { return { type: RECEIVE_POSTS, reddit, posts: json.data.children.map(child => child.data), receivedAt: Date.now() } }
export function fetchPosts(reddit) { return dispatch => { dispatch(requestPosts(reddit)) return fetch(`http://www.reddit.com/r/${reddit}.json`) .then(response => response.json()) .then(json => dispatch(receivePosts(reddit, json)) ) } }
コード例 Action Creator(非同期)export function fetchPosts(reddit) { return dispatch => { dispatch(requestPosts(reddit)) // リクエスト開始アクション
return fetch(`http://www.reddit.com/r/${reddit}.json`) .then(response => response.json()) .then(json => dispatch(receivePosts(reddit, json)) // リクエスト完了アクション ) } }
非同期関数の前で1回、コールバックが呼ばれたらさら
に1回別のアクション関数を呼ぶ
↑の挙動をするためにredux-thunkと言うミドルウェ
アを使う
https://github.com/gaearon/redux-thunk
コード例 Reducer
アクションに応じて状態を変化させる関数を書く
Reducerは階層化、モジュール化することができる
function todoApp(state = initialState, action) { switch (action.type) { case SET_VISIBILITY_FILTER: return Object.assign({}, state, { visibilityFilter: action.filter }) default: return state } }
コード例 階層化したReducer長くなったので次のページで
export default function todos(state = [], action) { switch (action.type) { case 'ADD_TODO': return state.concat([ action.text ]) default: return state } }
export default function counter(state = 0, action) { switch (action.type) { case 'INCREMENT': return state + 1 case 'DECREMENT': return state - 1 default: return state } }
import { combineReducers } from 'redux' import todos from './todos' import counter from './counter'
export default combineReducers({ todos, counter })
コード例 階層化したReducer
↑の感じで分割したReducerをcombineReducerでまとめる
Stateの各メンバがconbineReducersに定義したReducer名に対応している(次で説明)
import { combineReducers } from 'redux' import todos from './todos' import counter from './counter'
export default combineReducers({ todos, counter })
コード例 階層化したReducer
export default combineReducers({ todos, counter })
// 全体のState { todos: [ ”朝ごはんを食べる”, ”js祭に参加する”, ], counter }
こんな感じでStateとconbineReducersが対応している
コード例 Store
ここら辺はほぼ定型です
ぶちゃけ1回書いたら後はほとんど変えないです
import { createStore } from 'redux' import todoApp from './reducers'
// Soreを宣言、Reducerはここで渡す let store = createStore(todoApp);
// アクション発行 store.dispatch(addTodo(''));
// stateに変化があれば、それをViewに伝える sore.subscribe(()=> { // 現在のStateを取得
var state = store.getState();
// ViewにStateを渡す
View(state); });
Viewには何を使えばいいの
React.jsを使うことが多いらしいです
Reactを使う場合、Viewに状態を持たせたく
ないので極力Stateを使わないようにします
理想では同じプロパティを渡されたら、いつでも同じDomをレンダリングするということ
Reduxを入れてよかったこと
fluxパターンなだけあって、コードの見通しが良くなった
画面の再利用性が高まった
Reduxで作った画面をダイアログ化するということをやりましたが、比較的簡単に実現できました
Reduxを使ってみての課題
Dom描画がすごく遅くなることがあった
バリデーションを実装したけど、入力が完了するたびに再描画処理が走る
要素が3000個以上もあると、Reactの
Shadow Domもあてにならない
Reduxを始めるには
当たり前ですが、grunt、gulpなどのフロントエンドビルド環境が必要です
es6は必須ではないですが、サンプルはes6で書かれたものが多いので導入した方がスムーズです
Reduxを勉強するには
公式ドキュメントを読めば、大体分かります
http://redux.js.org/index.html
basic、Async Actionを3時間くらいかけて読んでイメージを掴みました
ご清聴ありがとう ございました