# 生態系統
Redux 是一個體小精悍的庫,但它相關的內容和 API 都是精挑細選的,目的是衍生出豐富的工具集和可擴展的生態系統。社區已經創建了各種各樣的有用的插件、庫和工具。使用 Redux 時并不需要您非要使用這些插件,但是它們可以幫助您更容易地實現特性并解決應用程序中的問題。
如果需要關于 Redux 所有內容的列表,推薦移步至 [Awesome Redux](https://github.com/xgrommx/awesome-redux)。它包含了示例、樣板代碼、中間件、工具庫,還有很多其它相關內容。要想學習 React 和 Redux ,[React/Redux Links](https://github.com/markerikson/react-redux-links) 包含了教程和不少有用的資源,[Redux Ecosystem Links](https://github.com/markerikson/redux-ecosystem-links) 則列出了 許多 Redux 相關的庫及插件。
本頁將只列出由 Redux 維護者審查過的一部分內容。不要因此打消嘗試其它工具的信心!整個生態發展得太快,我們沒有足夠的時間去關注所有內容。建議只把這些當作“內部推薦”,如果你使用 Redux 創建了很酷的內容,不要猶豫,馬上發個 PR 吧。
## 目錄
- [與不同框架綁定](#library-integration-and-bindings)
- [Reducers](#reducers)
- [組合 Reducer](#reducer-combination)
- [Reducer 結構](#reducer-composition)
- [高階 Reducers](#higher-order-reducers)
- [Actions](#actions)
- [工具集](#utilities)
- [Store](#store)
- [更改訂閱](#change-subscriptions)
- [批處理](#batching)
- [持久化](#persistence)
- [不可變(Immutable)數據](#immutable-data)
- [數據結構](#data-structures)
- [不可變更新(Immutable Update)實用程序](#immutable-update-utilities)
- [Immutable/Redux 互操作](#immutable-redux-interop)
- [副作用(Side Effects)](#side-effects)
- [廣泛使用](#widely-used)
- [Promises](#promises)
- [中間件](#middleware)
- [Networks and Sockets](#networks-and-sockets)
- [異步行為](#async-behavior)
- [分析](#analytics)
- [實體和集合](#entities-and-collections)
- [組件 state 和封裝](#component-state-and-encapsulation)
- [開發者工具](#dev-tools)
- [Debuggers and Viewers](#debuggers-and-viewers)
- [日志](#logging)
- [突變檢測](#mutation-detection)
- [測試](#testing)
- [路由](#routing)
- [Forms](#forms)
- [更高級別的抽象](#higher-level-abstractions)
- [社區公約](#community-conventions)
<a id="library-integration-and-bindings"></a>
## 與不同框架綁定
**[reduxjs/react-redux](https://github.com/reduxjs/react-redux)**
Redux 與 react 的官方綁定庫,由 Redux 團隊維護
**[angular-redux/ng-redux](https://github.com/angular-redux/ng-redux)**
Redux 與 Angular 1 的綁定庫
**[angular-redux/store](https://github.com/angular-redux/store)**
Redux 與 Angular 2+ 的綁定庫
**[ember-redux/ember-redux](https://github.com/ember-redux/ember-redux)**
Redux 與 Ember 的綁定庫
**[glimmer-redux/glimmer-redux](glimmer-redux/glimmer-redux)**
Redux 綁定 Ember 的 Glimmer 組件引擎
**[tur-nr/polymer-redux](https://github.com/tur-nr/polymer-redux)**
Redux 與 Polymer 的綁定庫
**[lastmjs/redux-store-element](https://github.com/lastmjs/redux-store-element)**
Redux 與自定義組件的綁定庫
## Reducers
<a id="reducer-combination"></a>
#### 組合 Reducer
**[ryo33/combineSectionReducers](https://github.com/ryo33/combine-section-reducers)**
`combineReducers` 的擴展版本,它允許將 `state` 作為第三個參數傳遞給所有的子 reducer。
**[KodersLab/topologically-combine-reducers](https://github.com/KodersLab/topologically-combine-reducers)**
一種 `combineReducers` 變體,定義 reducer 之間的相互依賴用于調用排序和數據傳遞
```js
var masterReducer = topologicallyCombineReducers(
{ auth, users, todos },
// 定義依賴樹
{ auth: ['users'], todos: ['auth'] }
)
```
<a id="reducer-composition"></a>
#### Reducer 結構
**[acdlite/reduce-reducers](https://github.com/acdlite/reduce-reducers)**
在同一級別提供 reducer 的順序組合
```js
const combinedReducer = combineReducers({ users, posts, comments })
const rootReducer = reduceReducers(combinedReducer, otherTopLevelFeatureReducer)
```
**[mhelmer/redux-xforms](https://github.com/mhelmer/redux-xforms)**
一組可組合的 reducer 變體。
```js
const createByFilter = (predicate, mapActionToKey) =>
compose(
withInitialState({}), // inject initial state as {}
withFilter(predicate), // let through if action has filterName
updateSlice(mapActionToKey), // update a single key in the state
isolateSlice(mapActionToKey) // run the reducer on a single state slice
)
```
**[adrienjt/redux-data-structures](https://github.com/adrienjt/redux-data-structures)**
Reducer 工廠函數,用于常見數據結構:計數器,映射,列表(隊列,堆棧),集合
```js
const myCounter = counter({
incrementActionTypes: ['INCREMENT'],
decrementActionTypes: ['DECREMENT']
})
```
<a id="higher-order-reducers"></a>
#### 高階 Reducers
**[omnidan/redux-undo](https://github.com/omnidan/redux-undo)**
輕松為 reducer 實現 undo/redo 和 action 的歷史記錄功能。
**[omnidan/redux-ignore](https://github.com/omnidan/redux-ignore)**
通過數組或過濾器函數忽略 redux action
**[omnidan/redux-recycle](https://github.com/omnidan/redux-recycle)**
在某些 action 上重置 redux 狀態
**[ForbesLindesay/redux-optimist](https://github.com/ForbesLindesay/redux-optimist)**
reducer 增強器,用于啟用與類型無關的樂觀更新
## Actions
**[reduxactions/redux-actions](https://github.com/reduxactions/redux-actions)**
Redux 的 Flux 標準 action 實用程序。
```js
const increment = createAction('INCREMENT')
const reducer = handleActions({ [increment]: (state, action) => state + 1 }, 0)
const store = createStore(reducer)
store.dispatch(increment())
```
**[BerkeleyTrue/redux-create-types](https://github.com/BerkeleyTrue/redux-create-types)**
根據命名空間創建標準和異步 action type。
```js
export const types = createTypes(
['openModal', createAsyncTypes('fetch')],
'app'
)
// { openModal : "app.openModal", fetch : { start : "app.fetch.start", complete: 'app.fetch.complete' } }
```
**[maxhallinan/kreighter](https://github.com/maxhallinan/kreighter)**
根據類型和預期字段生成 action creator
```js
const formatTitle = (id, title) => ({
id,
title: toTitleCase(title)
})
const updateBazTitle = fromType('UPDATE_BAZ_TITLE', formatTitle)
updateBazTitle(1, 'foo bar baz')
// -> { type: 'UPDATE_BAZ_TITLE', id: 1, title: 'Foo Bar Baz', }
```
<a id="utilities"></a>
## 工具集
**[reduxjs/reselect](https://github.com/reduxjs/reselect)**
創建可組合的 memoized 選擇器函數,以便從 store state 有效地導出數據
```js
const taxSelector = createSelector(
[subtotalSelector, taxPercentSelector],
(subtotal, taxPercent) => subtotal * (taxPercent / 100)
)
```
**[paularmstrong/normalizr](https://github.com/paularmstrong/normalizr)**
根據模式規范化嵌套 JSON
```js
const user = new schema.Entity('users')
const comment = new schema.Entity('comments', { commenter: user })
const article = new schema.Entity('articles', {
author: user,
comments: [comment]
})
const normalizedData = normalize(originalData, article)
```
**[planttheidea/selectorator](https://github.com/planttheidea/selectorator)**
對于常見 selector 用例的 reselect 的抽象化
```js
const getBarBaz = createSelector(
['foo.bar', 'baz'],
(bar, baz) => `${bar} ${baz}`
)
getBarBaz({ foo: { bar: 'a' }, baz: 'b' }) // "a b"
```
## Store
<a id="change-subscriptions"></a>
#### 更改訂閱
**[jprichardson/redux-watch](https://github.com/jprichardson/redux-watch)**
根據 key path 或 selector 監視狀態更改
```js
let w = watch(() => mySelector(store.getState()))
store.subscribe(
w((newVal, oldVal) => {
console.log(newval, oldVal)
})
)
```
**[ashaffer/redux-subscribe](https://github.com/ashaffer/redux-subscribe)**
集中訂閱基于 path 的 state 更改
```js
store.dispatch( subscribe("users.byId.abcd", "subscription1", () => {} );
```
<a id="batching"></a>
#### 批處理
**[tappleby/redux-batched-subscribe](https://github.com/tappleby/redux-batched-subscribe)**
可以取消訂閱通知的 store 增強器
```js
const debounceNotify = _.debounce(notify => notify())
const store = createStore(
reducer,
initialState,
batchedSubscribe(debounceNotify)
)
```
**[manaflair/redux-batch](https://github.com/manaflair/redux-batch)**
store 增強器,允許 dispatch action 數組
```js
const store = createStore(reducer, reduxBatch)
store.dispatch([{ type: 'INCREMENT' }, { type: 'INCREMENT' }])
```
**[laysent/redux-batch-actions-enhancer](https://github.com/laysent/redux-batch-actions-enhancer)**
store 增強器,接受批量 action
```js
const store = createStore(reducer, initialState, batch().enhancer)
store.dispatch(createAction({ type: 'INCREMENT' }, { type: 'INCREMENT' }))
```
**[tshelburne/redux-batched-actions](https://github.com/tshelburne/redux-batched-actions)**
處理批量 action 的高階 reducer
```js
const store = createStore(enableBatching(reducer), initialState)
store.dispatch(batchActions([{ type: 'INCREMENT' }, { type: 'INCREMENT' }]))
```
<a id="persistence"></a>
#### 持久化
**[rt2zz/redux-persist](https://github.com/rt2zz/redux-persist)**
使用許多可擴展的選項,持久化和補充 Redux store。
```js
const store = createStore(reducer, autoRehydrate())
persistStore(store)
```
**[react-stack/redux-storage](https://github.com/react-stack/redux-storage)**
Redux 的持久層,具有靈活的后端。
```js
const reducer = storage.reducer(combineReducers(reducers))
const engine = createEngineLocalStorage('my-save-key')
const storageMiddleware = storage.createMiddleware(engine)
const store = createStore(reducer, applyMiddleware(storageMiddleware))
```
**[redux-offline/redux-offline](https://github.com/redux-offline/redux-offline)**
用于 Offline-First 應用程序的持久 store ,支持積極的 UI 更新(optimistic UI)
```js
const store = createStore(reducer, offline(offlineConfig))
store.dispatch({
type: 'FOLLOW_USER_REQUEST',
meta: { offline: { effect: {}, commit: {}, rollback: {} } }
})
```
<a id="immutable-data"></a>
## 不可變(Immutable)數據
<a id="data-structures"></a>
#### 數據結構
**[facebook/immutable-js](https://github.com/facebook/immutable-js)**
Javascript 的不可變持久數據集合
```js
const map1 = Map({ a: 1, b: 2, c: 3 })
const map2 = map1.set('b', 50)
map1.get('b') // 2
map2.get('b') // 50
```
**[rtfeldman/seamless-immutable](https://github.com/rtfeldman/seamless-immutable)**
凍結的不可變數組/對象,向后兼容 JS
```js
const array = Immutable(['totally', 'immutable', { a: 42 }])
array[0] = 'edited' // does nothing
```
**[planttheidea/crio](https://github.com/planttheidea/crio)**
具有 API 的不可變 JS 對象
```js
const foo = crio(['foo'])
const fooBar = foo.push('bar') // new array: ['foo', 'bar']
```
**[aearly/icepick](https://github.com/aearly/icepick)**
用于將凍結的 JS 對象視為持久不可變集合的實用程序。
```js
const newObj = icepick.assocIn({ c: { d: 'bar' } }, ['c', 'd'], 'baz')
const obj3 = icepicke.merge(obj1, obj2)
```
<a id="immutable-update-utilities"></a>
#### 不可變更新(Immutable Update)實用程序
**[mweststrate/immer](https://github.com/mweststrate/immer)**
運用代理使用普通的更新代碼進行不可變更新
```js
const nextState = produce(baseState, draftState => {
draftState.push({ todo: 'Tweet about it' })
draftState[1].done = true
})
```
**[kolodny/immutability-helper](https://github.com/kolodny/immutability-helper)**
react-addons-update 的直接替代品
```js
const newData = update(myData, {
x: { y: { z: { $set: 7 } } },
a: { b: { $push: [9] } }
})
```
**[mariocasciaro/object-path-immutable](https://github.com/mariocasciaro/object-path-immutable)**
更簡單的替代 immutability-helpers 和 Immutable.js 的庫
```js
const newObj = immutable(obj)
.set('a.b', 'f')
.del(['a', 'c', 0])
.value()
```
**[debitoor/dot-prop-immutable](https://github.com/debitoor/dot-prop-immutable)**
dot-prop 庫的不可變(Immutable)版本,帶有一些擴展
```js
const newState = dotProp.set(state, `todos.${index}.complete`, true)
const endOfArray = dotProp.get(obj, 'foo.$end')
```
<a id="immutable-redux-interop"></a>
#### Immutable/Redux 互操作
**[gajus/redux-immutable](https://github.com/gajus/redux-immutable)**
與 Immutable.js Maps 一起使用的 combineReducers 等價物
```js
const initialState = Immutable.Map()
const rootReducer = combineReducers({})
const store = createStore(rootReducer, initialState)
```
**[eadmundo/redux-seamless-immutable](https://github.com/eadmundo/redux-seamless-immutable)**
與 combineReducers 等效,與 seamless-immutable value 一起使用
```js
import { combineReducers } from 'redux-seamless-immutable';
const rootReducer = combineReducers({ userReducer, posts
```
<a id="side-effects"></a>
## 副作用(Side Effects)
<a id="widely-used"></a>
#### 廣泛使用
**[gaearon/redux-thunk](https://github.com/gaearon/redux-thunk)**
調度(dispatch)函數,調用并將 `dispatch` 和 `getState` 作為參數。 這充當了 AJAX 調用和其他異步行為的方法。
**適用于**: 入門、簡單的異步和復雜的同步邏輯。
```js
function fetchData(someValue) {
return (dispatch, getState) => {
dispatch({type : "REQUEST_STARTED"});
myAjaxLib.post("/someEndpoint", {data : someValue})
.then(response => dispatch({type : "REQUEST_SUCCEEDED", payload : response})
.catch(error => dispatch({type : "REQUEST_FAILED", error : error});
};
}
function addTodosIfAllowed(todoText) {
return (dispatch, getState) => {
const state = getState();
if(state.todos.length < MAX_TODOS) {
dispatch({type : "ADD_TODO", text : todoText});
}
}
}
```
**[redux-saga/redux-saga](https://github.com/redux-saga/redux-saga)**
使用同步查找生成器函數處理異步邏輯。 Sagas 返回 effect 的描述, 這些 effect 由 saga 中間件執行,并且像 JS 應用程序的“后臺線程”。
**適用于**: 復雜的異步邏輯,解耦的工作流程
```js
function* fetchData(action) {
const { someValue } = action
try {
const response = yield call(myAjaxLib.post, '/someEndpoint', {
data: someValue
})
yield put({ type: 'REQUEST_SUCCEEDED', payload: response })
} catch (error) {
yield put({ type: 'REQUEST_FAILED', error: error })
}
}
function* addTodosIfAllowed(action) {
const { todoText } = action
const todos = yield select(state => state.todos)
if (todos.length < MAX_TODOS) {
yield put({ type: 'ADD_TODO', text: todoText })
}
}
```
**[redux-observable/redux-observable](https://github.com/redux-observable/redux-observable)**
使用稱為 “epics” 的 RxJS 可觀察鏈處理異步邏輯。
撰寫和取消異步操作以創建副作用等。
**適用于**: 復雜的異步邏輯,解耦的工作流程
```js
const loginRequestEpic = action$ =>
action$
.ofType(LOGIN_REQUEST)
.mergeMap(({ payload: { username, password } }) =>
Observable.from(postLogin(username, password))
.map(loginSuccess)
.catch(loginFailure)
)
const loginSuccessfulEpic = action$ =>
action$
.ofType(LOGIN_SUCCESS)
.delay(2000)
.mergeMap(({ payload: { msg } }) => showMessage(msg))
const rootEpic = combineEpics(loginRequestEpic, loginSuccessfulEpic)
```
**[redux-loop/redux-loop](https://github.com/redux-loop/redux-loop)**
Elm 體系結構的一個端口,用于 Redux,允許您通過從 Reducer 返回它們來自然而純粹地對您的 effect 進行排序。 reducer 現在返回狀態值和副作用描述。
**適用于**: 試圖盡可能地像 Elm 一樣使用 Redux + JS
```js
export const reducer = (state = {}, action) => {
switch (action.type) {
case ActionType.LOGIN_REQUEST:
const { username, password } = action.payload
return loop(
{ pending: true },
Effect.promise(loginPromise, username, password)
)
case ActionType.LOGIN_SUCCESS:
const { user, msg } = action.payload
return loop(
{ pending: false, user },
Effect.promise(delayMessagePromise, msg, 2000)
)
case ActionType.LOGIN_FAILURE:
return { pending: false, err: action.payload }
default:
return state
}
}
```
**[jeffbski/redux-logic](https://github.com/jeffbski/redux-logic)**
使用 observable 構建的副作用 lib,但允許使用回調、promises、async/await 或 observables。 提供 action 的聲明性處理。
**適用于**: 非常分離的異步邏輯
```js
const loginLogic = createLogic({
type: Actions.LOGIN_REQUEST,
process({ getState, action }, dispatch, done) {
const { username, password } = action.payload
postLogin(username, password)
.then(
({ user, msg }) => {
dispatch(loginSucceeded(user))
setTimeout(() => dispatch(showMessage(msg)), 2000)
},
err => dispatch(loginFailure(err))
)
.then(done)
}
})
```
<a id="promises"></a>
#### Promises
**[acdlite/redux-promise](https://github.com/acdlite/redux-promise)**
調度(Dispatch) promise 作為 action 的有效負載,并在 promise resolve 或 reject 時調度 FSA 兼容(FSA-compliant)的 action 。
```js
dispatch({ type: 'FETCH_DATA', payload: myAjaxLib.get('/data') })
// will dispatch either {type : "FETCH_DATA", payload : response} if resolved,
// or dispatch {type : "FETCH_DATA", payload : error, error : true} if rejected
```
**[lelandrichardson/redux-pack](https://github.com/lelandrichardson/redux-pack)**
明智的、聲明性的、基于約定的處理 promise,可以指導用戶朝著良好的方向發展而不會暴露出全部的調度(dispatch)功能。
```js
dispatch({type : "FETCH_DATA", payload : myAjaxLib.get("/data") });
// in a reducer:
case "FETCH_DATA": =
return handle(state, action, {
start: prevState => ({
...prevState,
isLoading: true,
fooError: null
}),
finish: prevState => ({ ...prevState, isLoading: false }),
failure: prevState => ({ ...prevState, fooError: payload }),
success: prevState => ({ ...prevState, foo: payload }),
});
```
<a id="middleware"></a>
## 中間件
<a id="networks-and-sockets"></a>
#### Networks and Sockets
**[svrcekmichal/redux-axios-middleware](https://github.com/svrcekmichal/redux-axios-middleware)**
使用 Axios 獲取數據并調度(dispatch)啟動 / 成功 / 失敗 action。
```js
export const loadCategories() => ({ type: 'LOAD', payload: { request : { url: '/categories'} } });
```
**[agraboso/redux-api-middleware](https://github.com/agraboso/redux-api-middleware)**
通過讀取 API 調用 action、獲取數據和調度 FSA
```js
const fetchUsers = () => ({
[CALL_API]: {
endpoint: 'http://www.example.com/api/users',
method: 'GET',
types: ['REQUEST', 'SUCCESS', 'FAILURE']
}
})
```
**[itaylor/redux-socket.io](https://github.com/itaylor/redux-socket.io)**
socket.io 和 redux 之間的固定連接器。
```js
const store = createStore(reducer, applyMiddleware(socketIoMiddleware))
store.dispatch({ type: 'server/hello', data: 'Hello!' })
```
**[tiberiuc/redux-react-firebase](https://github.com/tiberiuc/redux-react-firebase)**
Firebase、React 和 Redux 之間的集成。
<a id="async-behavior"></a>
#### 異步行為
**[rt2zz/redux-action-buffer](https://github.com/rt2zz/redux-action-buffer)**
將所有操作緩沖到隊列中,直到滿足斷路器條件,此時釋放隊列
**[wyze/redux-debounce](https://github.com/wyze/redux-debounce)**
符合 FSA 標準的 Redux 中間件可以實現 action 的防抖。
**[mathieudutour/redux-queue-offline](https://github.com/mathieudutour/redux-queue-offline)**
離線時將 action 加入隊列,并在重新聯機時 dispatch 它們。
<a id="analytics"></a>
#### 分析
**[rangle/redux-beacon](https://github.com/rangle/redux-beacon)**
與任何分析服務集成,可以在離線時跟蹤,并將分析邏輯與應用邏輯分離。
**[hyperlab/redux-insights](https://github.com/hyperlab/redux-insights)**
使用簡單的 API 進行分析和跟蹤,以編寫自己的適配器
**[markdalgleish/redux-analytics](https://github.com/markdalgleish/redux-analytics)**
使用 meta 分析值監視 Flux 標準操作并處理它們
<a id="entities-and-collections"></a>
## 實體和集合
**[tommikaikkonen/redux-orm](https://github.com/tommikaikkonen/redux-orm)**
一個簡單的不可變 ORM,用于管理 Redux sotre 中的關系數據。
**[Versent/redux-crud](https://github.com/Versent/redux-crud)**
基于約定的 action 和 reducer,用于處理 CRUD 邏輯
**[kwelch/entities-reducer](https://github.com/kwelch/entities-reducer)**
處理 Normalizr 數據的高階 reducer
**[amplitude/redux-query](https://github.com/amplitude/redux-query)**
聲明與組件共存的數據依賴關系,在組件 mount 時運行查詢、執行樂觀更新以及使用 Redux action 觸發服務器更改。
**[cantierecreativo/redux-bees](https://github.com/cantierecreativo/redux-bees)**
聲明性 JSON-API 交互,用于規范化數據,與可以運行查詢的 React 高階組件(HOC)交互
**[GetAmbassador/redux-clerk](https://github.com/GetAmbassador/redux-clerk)**
具有規范化、樂觀更新、同步/異步 action creator、 selector 和可擴展 reducer 的異步 CRUD 處理。
**[shoutem/redux-io](https://github.com/shoutem/redux-io)**
具有異步 CRUD、規范化、樂觀更新、緩存、數據狀態和錯誤處理的 JSON-API 抽象。
**[jmeas/redux-resource](https://github.com/jmeas/redux-resource)**
用于管理“資源”的小而強大的系統:持久存儲到遠程服務器的數據。
<a id="component-state-and-encapsulation"></a>
## 組件 state 和封裝
**[tonyhb/redux-ui](https://github.com/tonyhb/redux-ui)**
用于 UI state 的“塊級范圍”。 裝飾組件以聲明數據字段,使這些數據字段成為 props 并可由嵌套子項更新。
```js
@ui({
key: 'some-name',
state: { uiVar1: '', uiVar2: (props, state) => state.someValue },
reducer: (state, action) => {}
})
class YourComponent extends React.Component {}
```
**[threepointone/redux-react-local](https://github.com/threepointone/redux-react-local)**
Redux 中的本地組件 state,用于處理組件 action
```js
@local({
ident: 'counter', initial: 0, reducer : (state, action) => action.me ? state + 1 : state }
})
class Counter extends React.Component {
```
**[epeli/lean-redux](https://github.com/epeli/lean-redux)**
使 Redux 中的組件的 state 與 setState 一樣簡單
```js
const DynamicCounters = connectLean(
scope: "dynamicCounters",
getInitialState() => ({counterCount : 1}),
addCounter, removeCounter
)(CounterList);
```
**[ioof-holdings/redux-subspace](https://github.com/ioof-holdings/redux-subspace)**
為分離的微前端創建獨立的 “sub-store”,集成了 React、sagas 和 observables
```js
const reducer = combineReducers({
subApp1: namespaced('subApp1')(counter),
subApp2: namespaced('subApp2')(counter)
})
const subApp1Store = subspace(state => state.subApp1, 'subApp1')(store)
const subApp2Store = subspace(state => state.subApp2, 'subApp2')(store)
subApp1Store.dispatch({ type: 'INCREMENT' })
console.log('store state:', store.getState()) // { "subApp1": { value: 2 }, "subApp2": { value: 1 } }
```
**[DataDog/redux-doghouse](https://github.com/DataDog/redux-doghouse)**
旨在通過將 actIon 和 reducer 作用于組件的特定實例,使 Redux 更易于構建可重用組件。
```js
const scopeableActions = new ScopedActionFactory(actionCreators)
const actionCreatorsScopedToA = scopeableActions.scope('a')
actionCreatorsScopedToA.foo('bar') //{ type: SET_FOO, value: 'bar', scopeID: 'a' }
const boundScopeableActions = bindScopedActionFactories(
scopeableActions,
store.dispatch
)
const scopedReducers = scopeReducers(reducers)
```
<a id="dev-tools"></a>
## 開發者工具
<a id="debuggers-and-viewers"></a>
#### Debuggers and Viewers
**[reduxjs/redux-devtools](https://github.com/reduxjs/redux-devtools)**
Dan Abramov 最初的 Redux DevTools 實現,專為在應用程序內顯示 state 和 time-travel 調試而構建
**[zalmoxisus/redux-devtools-extension](https://github.com/zalmoxisus/redux-devtools-extension)**
Mihail Diordiev 的瀏覽器擴展,捆綁了多個 state 監視器視圖,并增加了與瀏覽器自己的開發工具的集成
**[infinitered/reactotron](https://github.com/infinitered/reactotron)**
用于檢查 React 和 React Native 應用程序的跨平臺 Electron 應用程序,包括應用程序狀態、API 請求、性能、錯誤、saga 和操作調度。
<a id="DevTools Monitors"></a>
#### 開發者工具監視器
**[Log Monitor](https://github.com/reduxjs/redux-devtools-log-monitor)**
Redux DevTools 默認監視器,提供樹狀視圖
**[Dock Monitor](https://github.com/reduxjs/redux-devtools-dock-monitor)**
Redux DevTools 監視器的可調整大小和可移動的底座
**[Slider Monitor](https://github.com/calesce/redux-slider-monitor)**
Redux DevTools 的自定義監視器,用于重放錄制的 Redux 操作
**[Inspector](https://github.com/alexkuz/redux-devtools-inspector)**
Redux DevTools 的自定義監視器,可讓您過濾操作,檢查差異,并在狀態中固定深層路徑以觀察其更改
**[Diff Monitor](https://github.com/whetstone/redux-devtools-diff-monitor)**
Redux DevTools 的監視器,用于在 action 之間區分 Redux store 突變
**[Filterable Log Monitor](https://github.com/bvaughn/redux-devtools-filterable-log-monitor/)**
樹狀可篩選視圖的 Redux DevTools 監視器
**[Chart Monitor](https://github.com/romseguy/redux-devtools-chart-monitor)**
Redux DevTools 的圖表監視器
**[Filter Actions](https://github.com/zalmoxisus/redux-devtools-filter-actions)**
Redux DevTools 可組合監視器,具有過濾 action 的能力
<a id="logging"></a>
#### 日志
**[evgenyrodionov/redux-logger](https://github.com/evgenyrodionov/redux-logger)**
記錄顯示 action、state 和差異的中間件
**[inakianduaga/redux-state-history](https://github.com/inakianduaga/redux-state-history)**
提供 time-travel 和高效的 action 錄制功能,包括導入 / 導出 action 日志和 action 播放的增強器。
**[joshwcomeau/redux-vcr](https://github.com/joshwcomeau/redux-vcr)**
實時記錄和重播用戶會話
**[socialtables/redux-unhandled-action](https://github.com/socialtables/redux-unhandled-action)**
在開發中對改變 state 的 action 發出警告
<a id="mutation-detection"></a>
#### 突變檢測
**[leoasis/redux-immutable-state-invariant](https://github.com/leoasis/redux-immutable-state-invariant)**
當您嘗試在調度(dispatch)內或調度(dispatch)之間改變狀態時拋出錯誤的中間件。
**[flexport/mutation-sentinel](https://github.com/flexport/mutation-sentinel)**
幫助您在運行時深入檢測突變并在代碼庫中強制實現不變性(immutability)。
**[mmahalwy/redux-pure-connect](https://github.com/mmahalwy/redux-pure-connect)**
檢查并記錄 react-redux 的 connect 方法是否通過 `mapState` 函數創建了不純的 props。
<a id="testing"></a>
## 測試
**[arnaudbenard/redux-mock-store](https://github.com/arnaudbenard/redux-mock-store)**
一個模擬 store,用于將 dispatched action 保存在數組中以進行斷言
**[Workable/redux-test-belt](https://github.com/Workable/redux-test-belt)**
擴展 store API 以使其更容易斷言、隔離和操縱 store
**[conorhastings/redux-test-recorder](https://github.com/conorhastings/redux-test-recorder)**
根據應用程序中的操作自動生成 Reducer 測試的中間件
**[wix/redux-testkit](https://github.com/wix/redux-testkit)**
用于測試 Redux 項目的完整且固定的測試工具包(Reducer、selectors、actions、thunk)
**[jfairbank/redux-saga-test-plan](https://github.com/jfairbank/redux-saga-test-plan)**
使 saga 的集成和單元測試變得輕而易舉
<a id="routing"></a>
## 路由
**[ReactTraining/react-router-redux](https://github.com/ReactTraining/react-router/tree/master/packages/react-router-redux)**
保持 state 與路由同步
**[FormidableLabs/redux-little-router](https://github.com/FormidableLabs/redux-little-router)**
Redux 應用程序的一個小型路由,可以與 URL 進行通信
**[faceyspacey/redux-first-router](https://github.com/faceyspacey/redux-first-router)**
無縫 Redux-first 路由。 在 state 中考慮您的應用,而不是在路由或組件中,同時保持與地址欄同步。 一切都是 state。 連接您的組件,只需調度(dispatch)標準的 action。
<a id="forms"></a>
## Forms
**[erikras/redux-form](https://github.com/erikras/redux-form)**
一個功能齊全的庫,可以使 React HTML 表單在 Redux 中存儲其狀態。
**[davidkpiano/react-redux-form](https://github.com/davidkpiano/react-redux-form)**
React Redux Form 是一個 reducer creator 和 action creator 的集合,它們使 React 和 Redux 可以簡單而高效地實現最復雜和自定義的 form。
<a id="higher-level-abstractions"></a>
## 更高級別的抽象
**[keajs/kea](https://github.com/keajs/kea)**
Redux、Redux-Saga 和 Reselect 的抽象。 為您的應用程序的 action、reducer、selector 和 saga 提供框架。 它賦予 Redux 權限,使其與 setState 一樣簡單。 它減少了樣板和冗余,同時保持了可組合性。
**[jumpsuit/jumpstate](https://github.com/jumpsuit/jumpstate)**
基于 Redux 的簡化版本。 沒有 action creator 或顯式調度(dispatch),具有內置的簡單副作用(side effect)系統。
**[TheComfyChair/redux-scc](https://github.com/TheComfyChair/redux-scc)**
采用定義的結構并使用“行為”來創建一組 actions、reducer responses 和 selectors。
**[Bloomca/redux-tiles](https://github.com/Bloomca/redux-tiles)**
在 Redux 之上提供最小的抽象,以實現輕松的可組合性、簡單的異步請求和可靠的可測試性。
<a id="community-conventions"></a>
## 社區公約
**[Flux Standard Action](https://github.com/acdlite/flux-standard-action)**
Flux action object 的人性化標準
**[Canonical Reducer Composition](https://github.com/gajus/canonical-reducer-composition)**
嵌套 reducer 組合的固定標準
**[Ducks: Redux Reducer Bundles](https://github.com/erikras/ducks-modular-redux)**
捆綁 reducer、action type 和 action 的提議
- 自述
- 介紹
- 動機
- 核心概念
- 三大原則
- 先前技術
- 學習資源
- 生態系統
- 示例
- 基礎
- Action
- Reducer
- Store
- 數據流
- 搭配 React
- 示例:Todo List
- 高級
- 異步 Action
- 異步數據流
- Middleware
- 搭配 React Router
- 示例:Reddit API
- 下一步
- 技巧
- 配置 Store
- 遷移到 Redux
- 使用對象展開運算符
- 減少樣板代碼
- 服務端渲染
- 編寫測試
- 計算衍生數據
- 實現撤銷重做
- 子應用隔離
- 組織 Reducer
- Reducer 基礎概念
- Reducer 基礎結構
- Reducer 邏輯拆分
- Reducer 重構示例
- combineReducers 用法
- combineReducers 進階
- State 范式化
- 管理范式化數據
- Reducer 邏輯復用
- 不可變更新模式
- 初始化 State
- 結合 Immutable.JS 使用 Redux
- 常見問題
- 綜合
- Reducer
- 組織 State
- 創建 Store
- Action
- 不可變數據
- 代碼結構
- 性能
- 設計哲學
- React Redux
- 其它
- 排錯
- 詞匯表
- API 文檔
- createStore
- Store
- combineReducers
- applyMiddleware
- bindActionCreators
- compose
- react-redux 文檔
- API
- 排錯