Redux は reducer から理解するのがわかりやすい

Redux は reducer から理解するのがわかりやすい:

いくつか解説を眺めてみたが、最初から全部の流れを概観しようという解説や、action から入る解説は私にとって少しわかりにくかった。

少し理解が進んだ今、redux は reducer から理解すべきだ、と思う。

reducer を理解するといくつも疑問が生じる。その疑問を解消する形で理解の範囲を広げていく。


Reducer を理解する


(state, action) => newState

Reducer はただの関数だ。

一般的に (state, action) => newState とあらわせる(シグネチャとして)。

日本語に翻訳するなら、

「状態と作用をとって新しい状態を返す関数」

あるいはもっと噛み砕いて、

「状態に作用を加えて新しい状態を作る関数」

とも言えるかもしれない。

もちろん、新しい状態にさらに作用を加えれば、また別の状態が生まれる。

(newState, anotherAction) => newState2

もちろんこれは副作用のない関数だ。

state と action の組み合わせが同一であるならば、何度呼んでも同じ newState が返ってくる。


Array.prototype.reduce との類似

Array.prototype.reduce() という JavaScript の関数で例えてみよう。

時系列に沿って次のような action があって、なぜか配列に収まっていたとする。

[action1, action2, action3]

この action の配列によって作られる状態は次のようなものだ。

[action1, action2, action3].reduce((累積した状態, action) => { 
  // ... 
  // 状態に対して action が作用する処理 
  // const newState = ... 
 
  return newState // 新しい状態 = 次の累積した状態 
}, 初期状態) 
Array.prototype.reduce は初期状態に対し、コールバックによる配列要素の処理を累積させていくものだ。

さて、ここで渡されるコールバックのことを reducer という。
MDN doc のデモ でも reducer という単語が使われている。

MDNdocDemo
const array1 = [1, 2, 3, 4]; 
const reducer = (accumulator, currentValue) => accumulator + currentValue; 
 
// 1 + 2 + 3 + 4 
console.log(array1.reduce(reducer)); 
// expected output: 10 
この reducer と Redux の reducer はほとんど同じものである。

ただ、Redux においては action は時系列に沿って順次やってくるものであって、最初からおとなしく配列におさまっているものではない。


生じる疑問

さて、 reducer は状態の変化を司るが、これだけで状態を管理をすることはできない。

以下の疑問が当然生じてくるだろう。

  • reducer の返り値はどこに(誰が)保存するのか
  • reducer はどうやって呼ぶのか


reducer の返り値はどこに(誰が)保存するのか

A. store

具体的には createStore という関数から返されるオブジェクトである。

store = createStore(reducer[, 初期状態とかエンハンサとか]) 
 
// いろんな処理 
 
store.getState() // reducer の最新の返り値、すなわち現在の状態を得る 


reducer はどうやって呼ぶのか

A. store のメソッド経由で

このメソッドを dispatch という。

store.dispatch(action) 
state は store が持っているので、渡す必要はない。

dispatch の名前の由来は知らないので知りたいが、別に知る必要もない気もする。

とりあえず、メソッドの名前だ。


その他のあったらいいな


ActionCreator

そもそも action とはなんぞや。

上の方では作用と言っていたけれど、作用を表現するための決まった形式がある。

具体的には次のようなJSオブジェクトでしかない。

action
{ 
  type: 'ADD_OBJCET', 
  payload: object 
} 
ただ、この action を毎回作るのめんどくさい。

これを作る過程でいろんなロジックも必要になりそう。

それなら ActionCreator にまとめてしまえ。

// 上の action が返ってくるような関数 actionCreator を作っておく 
store.dispatch(addObjectCreator(object)) 
ちょっとオシャレ(?)になると自分で作ったアクションをそのまま dispatch しちゃったりする。

基本的に自由だ。

redux に必要というより react-redux に必要(便利)。


subscribe

状態変化の通知が欲しかったらコールバックを渡して購読する。

実際には dispatch のたびにコールバックが呼ばれるらしい。

store.subscribe(() => console.log(store.getState())) 
状態の監視ができる。

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)