Reduxはドキュメントがとても充実している。VIDEOのコースもあるし、Examplesもちゃんと考えられてるし、もちろんDocumentationもしっかりある。昨日、VIDEOコースに一通り目を通したので、今日はExamplesを見てみる。と言っても、自分自身ReactやJavaScriptの世界もそんなに得意ではないのでためになると思ったことを都度取り出すという感じにしたいと思う。
公式のExamplesはここにまとまっている。
Counter-valila
redux/examples/counter-vanilla at master · reactjs/redux
Counter系はこんな見た目。こちらはReactを使っていない実装。index.htmlしかない。
AsyncはsetTimeoutで書いている。
document.getElementById('incrementAsync') .addEventListener('click', function () { setTimeout(function () { store.dispatch({ type: 'INCREMENT' }) }, 1000) })
Counter
redux/examples/counter at master · reactjs/redux
Reduxの起点をrootにするのは真似しようかな。
<!DOCTYPE html> <html> <head> <title>Redux counter example</title> </head> <body> <div id="root"> </div> <script src="/static/bundle.js"></script> </body> </html>
これはProviderを利用していない実装だけど、rootのオブジェクトを一旦変数に入れるやり方は真似したい。下記の例ではrootELの部分。
const store = createStore(counter) const rootEl = document.getElementById('root') function render() { ReactDOM.render( <Counter value={store.getState()} onIncrement={() => store.dispatch({ type: 'INCREMENT' })} onDecrement={() => store.dispatch({ type: 'DECREMENT' })} />, rootEl ) }
こうやって値を取り出して使いやすくしてるのかな。
const { value, onIncrement, onDecrement } = this.props
スペースは、{' '}
で表現しているのかな。
<p> Clicked: {value} times {' '} <button onClick={onIncrement}> + </button> ... </p>
Todos
redux/examples/todos at master · reactjs/redux
Todo系の見た目はこんな感じ。
この辺りからディレクトリ構造が出来てくるので参考にできる。actionsとreducersとcomponentsとcontainersというふうに分かれている。App.jsはcomponentsにある。
componentsにあるものはdispatchもstoreも何も持ってない。 表示に徹している。参考になる。componentsとcontainersは包含関係というよりは役割で分けている。
reducersが複数になって、reducers/index.jsでまとめてる。
reducers/index.js
import { combineReducers } from 'redux' import todos from './todos' import visibilityFilter from './visibilityFilter' const todoApp = combineReducers({ todos, visibilityFilter }) export default todoApp
todoのreducer。Object.assign…は2番目の引数の3番目のプロパティを更新するというやつだったと思う。覚えなきゃ。
const todo = (state, action) => { switch (action.type) { case 'ADD_TODO': return { id: action.id, text: action.text, completed: false } case 'TOGGLE_TODO': if (state.id !== action.id) { return state } return Object.assign({}, state, { completed: !state.completed }) default: return state } }
Todos with Undo
redux/examples/todos-with-undo at master · reactjs/redux
ほとんど、Todosと同じだけど、reducerをReduxUndoというのでラップしているらしい。
recudersのtodo.jsの所に下記のようなものがある。これは、ちょっとちゃんとReduxUndoのことを調べて理解したほうがいいな。
import undoable, { distinctState } from 'redux-undo' ... const undoableTodos = undoable(todos, { filter: distinctState() }) export default undoableTodos
TodoMVC
redux/examples/todomvc at master · reactjs/redux
これは比較のためにあるということ。今まで見てきたのと全然違う書き方。複雑に感じる。ただ、これはちゃんと僕が理解できていない。これは後回し。
Shopping Cart
redux/examples/shopping-cart at master · reactjs/redux
規模が大きくなってきたときに使えるパターンが書かれているらしい。
- how to store entities in a normalized way by their IDs
- how to compose reducers on several levels
- how to define selectors alongside the reducers so the knowledge about the state shape is encapsulated
さらに、ロギングのReduxLogger、条件によってアクションを発火できる?ReduxThunkについても描かれている。
今日はちょっとこの辺でやめておく。入門レベルを超えてきた。ちょっとアプリを書いてから、続きを読んだほうが効率が良さそう。
その他のExample
- TreeView
- 深くネストした構造を扱うものらしい。確かにこのネストのハンドリングは知りたい。
- コードはシンプルなので、ちょっと見てみるのもありかも。
- Async
- 非同期のサーバーアクセスを扱う。これは興味あり。次の機会にちゃんと目を通そう。
- こちらもコードはシンプルなのでちゃんとしたアプリ作る必要が出てきたら目を通す。
- Universal
- サーバーレンダリングをするサンプル。
- RealWorld
- 最もちゃんとしたExample。ちゃんとサービス作るならここまでは押さえておきたい。
- keeping fetched entities in a normalized cache
- implementing a custom middleware for API calls
- rendering partially loaded data
- pagination
- caching responses
- displaying error messages
- routing
- Additionally, it includes Redux DevTools.
TreeViewのイメージ