Skip to content

Commit 148b461

Browse files
committed
feat(redux): Reduxの概要を追加 (#99)
* rename dir * chore: redux -> Redux * feat(redux): Reduxの概要を追加 * fix(redux): fix path of Redux * chore(redux): 三原則という表記に統一 * feat(redux): どう書けるをざっくりと追加 * fix(redux): fix example code * refactor(redux): split up redux-example.js
1 parent 0dd3076 commit 148b461

File tree

10 files changed

+126
-7
lines changed

10 files changed

+126
-7
lines changed

ja/Redux/README.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Redux
2+
3+
> この文章は[Redux][] [3.5.2](https://github.com/reactjs/redux/releases/tag/v3.5.2 "3.5.2")を元に書かれています。
4+
5+
[Redux][]はJavaScriptアプリケーションのStateを管理するライブラリで、
6+
[React](https://github.com/facebook/react "React")などと組み合わせアプリケーションを作成するために利用されています。
7+
8+
Reduxは[Flux](https://facebook.github.io/flux/ "Flux")アーキテクチャに類似する仕組みであるため、事前にFluxについて学習していると良いです。
9+
10+
Reduxには[Three Principles](http://redux.js.org/docs/introduction/ThreePrinciples.html "Three Principles | Redux")(以下、三原則)と呼ばれる3つの制約の上で成立しています。
11+
12+
- Single source of truth
13+
- アプリケーション全体のStateは一つのStateツリーとして保存される
14+
- State is read-only
15+
- StateはActionを経由しないと書き換えることができない
16+
- Changes are made with pure functions
17+
- Actionを受け取りStateを書き換えるReducerと呼ばれるpure functionを作る
18+
19+
この三原則についての詳細はドキュメントなどを参照してください。
20+
21+
- [Read Me | Redux](http://redux.js.org/)
22+
- [Getting Started with Redux - Course by @dan_abramov @eggheadio](https://egghead.io/series/getting-started-with-redux)
23+
24+
Reduxの使い方についてはここでは解説しませんが、Reduxの拡張である _Middleware_ も、この三原則に基づいた仕組みとなっています。
25+
26+
_Middleware_ という名前からも分かるように、[connect](../connect/README.md)の仕組みと類似点があります。
27+
[connect](../connect/README.md)の違いを意識しながら、Reduxの _Middleware_ の仕組みを見ていきましょう。
28+
29+
## どう書ける?
30+
31+
3行でReduxの仕組みを書くと以下のようになります。
32+
33+
- 操作を表現するオブジェクトをActionと呼ぶ - 一般にコマンドパターンのコマンドと同様のもの
34+
- Actionを受け取りStateを書き換える関数を _Reducer_ と呼ぶ - ReducerはStoreに事前に登録する
35+
- ActionをDispatch(`store.dispatch(action)`)することで、ActionをReducerへ通知する
36+
37+
Reduxの例として次のようなコードを見てみます。
38+
39+
[import, redux-example.js](../../src/Redux/redux-example.js)
40+
41+
1. `logger``crashReporter`のmiddlewareを適応した`createStore`関数を作る
42+
2. Reducerを登録したStoreを作成
43+
3. (Storeの変更をする)Actionをdispatch
44+
4. Actionを受け取り新しいStateを返すReducer関数
45+
5. Stateが変更されたら呼ばれる
46+
47+
というような流れで動作します。
48+
49+
上記の処理のうち、 3から4の間が _Middleware_ が処理する場所となっています。
50+
51+
`dispatch(action)` -> (_Middleware_ の処理) -> reducerにより新しいStateの作成 -> (Stateが変わったら) -> `subscribe`で登録したコールバックを呼ぶ
52+
53+
次は`applyMiddleware`がどのように _Middleware_ を登録しているのかを見ていきましょう。
54+
55+
## どういう仕組み?
56+
57+
- 高階関数をapplyしている
58+
- http://rackt.github.io/redux/docs/advanced/Middleware.html
59+
- その機構のコードへのリンク
60+
- その仕組みやプラグインについてドキュメントへのリンク
61+
62+
## 実装してみよう
63+
64+
- [ ] TODO
65+
- [ ] DispatcherベースのMiddleware
66+
67+
## どういう事に向いてる?
68+
69+
- [ ] TODO
70+
- アスペクト的に前後に処理を挟むことができる
71+
- ログへの利用
72+
- 値自体は直接操作するわけではないが、受取るデータは変換できる
73+
74+
## どういう事に向いていない?
75+
76+
- [ ] TODO
77+
- 変換の仕組み上、書き換え等を行うプラグインを扱いにくい
78+
79+
## この仕組みを使ってるもの
80+
81+
- Connectに似ている
82+
- _Middleware_もStateそのものを直接書き換える事はできません。
83+
- この部分が類似の仕組みを持つ[connect](../connect/README.md)との違いになっています。
84+
85+
86+
87+
[Redux]: https://github.com/reactjs/redux "reactjs/redux: Predictable state container for JavaScript apps"
File renamed without changes.
File renamed without changes.
File renamed without changes.

src/Redux/redux-example.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import {createStore, applyMiddleware} from "redux";
2+
import logger from "./logger";
3+
import crashReporter from "./timestamp";
4+
// 4. Actionを受け取り新しいStateを返すReducer関数
5+
const reducer = (state = {}, action) => {
6+
switch (action.type) {
7+
case "AddTodo":
8+
return Object.assign({}, state, {title: action.title});
9+
default:
10+
return state;
11+
}
12+
};
13+
// 1. `logger`と`crashReporter`のmiddlewareを適応した`createStore`関数を作る
14+
const createStoreWithMiddleware = applyMiddleware(logger, crashReporter)(createStore);
15+
16+
// 2. Reducerを登録したStoreを作成
17+
const store = createStoreWithMiddleware(reducer);
18+
19+
store.subscribe(() => {
20+
// 5. Stateが変更されたら呼ばれる
21+
const state = store.getState();
22+
// 現在のStateを取得
23+
console.log(state);
24+
});
25+
// 3. Storeの変更をするActionをdispatch
26+
store.dispatch({
27+
type: "AddTodo",
28+
title: "Todo title"
29+
});
File renamed without changes.

test/redux/apply-middleware-test.js renamed to test/Redux/apply-middleware-test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// LICENSE : MIT
22
"use strict";
33
const assert = require("power-assert");
4-
import applyMiddleware from "../../src/redux/apply-middleware";
5-
import Dispatcher from "../../src/redux/Dispatcher";
6-
import timestamp from "../../src/redux/timestamp";
7-
import createLogger from "../../src/redux/logger";
4+
import applyMiddleware from "../../src/Redux/apply-middleware";
5+
import Dispatcher from "../../src/Redux/Dispatcher";
6+
import timestamp from "../../src/Redux/timestamp";
7+
import createLogger from "../../src/Redux/logger";
88
describe("middleware", function () {
99
it("could apply logger middleware", function () {
1010
const dispatcher = new Dispatcher();

test/redux/logger-test.js renamed to test/Redux/logger-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"use strict";
33
const assert = require("power-assert");
44
import {createStore, applyMiddleware} from "redux";
5-
import createLogger from "../../src/redux/logger";
5+
import createLogger from "../../src/Redux/logger";
66
const initialState = {};
77
const reducer = (state = initialState, action) => state;
88

test/redux/timestamp-test.js renamed to test/Redux/timestamp-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"use strict";
33
const assert = require("power-assert");
44
import {createStore, applyMiddleware} from "redux";
5-
import timestamp from "../../src/redux/timestamp";
5+
import timestamp from "../../src/Redux/timestamp";
66
const initialState = {};
77
const reducer = (state = initialState, action) => {
88
switch (action.type) {

test/prh.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,7 @@ rules:
3030
- 文字列オブジェクト
3131

3232
- expected: わけでは
33-
patterns: 訳では
33+
patterns: 訳では
34+
35+
- expected: 三原則
36+
patterns: 3原則

0 commit comments

Comments
 (0)