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
-
- 深くネストした構造を扱うものらしい。確かにこのネストのハンドリングは知りたい。
- コードはシンプルなので、ちょっと見てみるのもありかも。
-
- 非同期のサーバーアクセスを扱う。これは興味あり。次の機会にちゃんと目を通そう。
- こちらもコードはシンプルなのでちゃんとしたアプリ作る必要が出てきたら目を通す。
-
- サーバーレンダリングをするサンプル。
-
- 最もちゃんとした 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 のイメージ