生態系統
Redux 是一個微型函式庫,但其合約和 API 經過仔細選擇,以衍生出工具和擴充功能的生態系統,而社群也創造出各種有用的附加元件、函式庫和工具。您不需要使用任何這些附加元件即可使用 Redux,但它們可以幫助您更輕鬆地在應用程式中實作功能和解決問題。
若要取得與 Redux 相關的函式庫、附加元件和工具的完整目錄,請查看Redux 生態系統連結清單。此外,React/Redux 連結清單包含教學和其他有用的資源,供任何人學習 React 或 Redux。
此頁面列出 Redux 維護人員親自審查的 Redux 相關附加元件,或是在社群中廣泛採用的附加元件。別讓這阻止您嘗試其他附加元件!生態系統發展得太快,我們只有有限的時間查看所有內容。將這些附加元件視為「員工精選」,如果您使用 Redux 建立了很棒的東西,請不要猶豫提交 PR。
目錄
程式庫整合和繫結
reduxjs/react-redux
Redux 的官方 React 繫結,由 Redux 團隊維護
angular-redux/ng-redux
Redux 的 Angular 1 繫結
ember-redux/ember-redux
Redux 的 Ember 繫結
glimmer-redux/glimmer-redux
Redux 繫結至 Ember 的 Glimmer 元件引擎
tur-nr/polymer-redux
Redux 繫結至 Polymer
lastmjs/redux-store-element Redux 繫結至自訂元素
Reducer
Reducer 組合
ryo33/combineSectionReducers
combineReducers
的擴充版本,允許將 state
作為第三個引數傳遞給所有區塊 reducer。
KodersLab/topologically-combine-reducers
combineReducers
變體,允許定義跨區塊相依性,以進行排序和資料傳遞
var masterReducer = topologicallyCombineReducers(
{ auth, users, todos },
// define the dependency tree
{ auth: ['users'], todos: ['auth'] }
)
Reducer 組成
acdlite/reduce-reducers
提供相同層級的 reducer 順序組成
const combinedReducer = combineReducers({ users, posts, comments })
const rootReducer = reduceReducers(combinedReducer, otherTopLevelFeatureReducer)
mhelmer/redux-xforms
可組合 reducer 轉換器的集合
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
常見資料結構的 reducer 工廠函式:計數器、對應、清單(佇列、堆疊)、集合
const myCounter = counter({
incrementActionTypes: ['INCREMENT'],
decrementActionTypes: ['DECREMENT']
})
高階 Reducer
omnidan/redux-undo
輕鬆為 reducer 進行復原/重做和動作記錄
omnidan/redux-ignore
依據陣列或篩選函式忽略 redux 動作
omnidan/redux-recycle
在特定動作上重設 redux 狀態
ForbesLindesay/redux-optimist
一個 reducer 增強器,用於啟用與類型無關的樂觀更新
工具
reduxjs/reselect
建立可組合的備忘選擇器函式,用於有效率地從儲存狀態衍生資料
const taxSelector = createSelector(
[subtotalSelector, taxPercentSelector],
(subtotal, taxPercent) => subtotal * (taxPercent / 100)
)
paularmstrong/normalizr
根據架構標準化巢狀 JSON
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
針對常見選擇器使用案例,對 Reselect 進行抽象化
const getBarBaz = createSelector(
['foo.bar', 'baz'],
(bar, baz) => `${bar} ${baz}`
)
getBarBaz({ foo: { bar: 'a' }, baz: 'b' }) // "a b"
儲存
變更訂閱
jprichardson/redux-watch
根據金鑰路徑或選擇器監控狀態變更
let w = watch(() => mySelector(store.getState()))
store.subscribe(
w((newVal, oldVal) => {
console.log(newval, oldVal)
})
)
ashaffer/redux-subscribe
根據路徑集中訂閱狀態變更
store.dispatch( subscribe("users.byId.abcd", "subscription1", () => {} );
批次處理
tappleby/redux-batched-subscribe
儲存增強器,可以延遲訂閱通知
const debounceNotify = _.debounce(notify => notify())
const store = configureStore({
reducer,
enhancers: [batchedSubscribe(debounceNotify)]
})
manaflair/redux-batch
儲存增強器,允許傳送動作陣列
const store = configureStore({
reducer,
enhancers: existingEnhancersArray => [
reduxBatch,
...existingEnhancersArray,
reduxBatch
]
})
store.dispatch([{ type: 'INCREMENT' }, { type: 'INCREMENT' }])
laysent/redux-batch-actions-enhancer
儲存增強器,接受批次處理動作
const store = configureStore({ reducer, enhancers: [batch().enhancer] })
store.dispatch(createAction({ type: 'INCREMENT' }, { type: 'INCREMENT' }))
tshelburne/redux-batched-actions
處理批次處理動作的高階 reducer
const store = configureStore({ reducer: enableBatching(rootReducer) })
store.dispatch(batchActions([{ type: 'INCREMENT' }, { type: 'INCREMENT' }]))
持久性
rt2zz/redux-persist
儲存並重新整理 Redux 儲存,並提供許多可擴充選項
const persistConfig = { key: 'root', version: 1, storage }
const persistedReducer = persistReducer(persistConfig, rootReducer)
export const store = configureStore({
reducer: persistedReducer,
middleware: getDefaultMiddleware =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER]
}
})
})
export const persistor = persistStore(store)
react-stack/redux-storage
Redux 的持久性層,具有彈性的後端
const reducer = storage.reducer(combineReducers(reducers))
const engine = createEngineLocalStorage('my-save-key')
const storageMiddleware = storage.createMiddleware(engine)
const store = configureStore({
reducer,
middleware: getDefaultMiddleware =>
getDefaultMiddleware.concat(storageMiddleware)
})
redux-offline/redux-offline
離線優先應用程式的持久性儲存,支援樂觀使用者介面
const store = configureStore({ reducer, enhancer: [offline(offlineConfig)] })
store.dispatch({
type: 'FOLLOW_USER_REQUEST',
meta: { offline: { effect: {}, commit: {}, rollback: {} } }
})
不可變資料
ImmerJS/immer
使用 Proxy 進行不可變更新,並使用一般的可變動程式碼
const nextState = produce(baseState, draftState => {
draftState.push({ todo: 'Tweet about it' })
draftState[1].done = true
})
副作用
廣泛使用
reduxjs/redux-thunk
傳送函式,會被呼叫並提供 dispatch
和 getState
作為參數。這充當 AJAX 呼叫和其他非同步行為的漏洞。
最適合:入門、簡單的非同步和複雜的同步邏輯。
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});
}
}
}
listenerMiddleware(Redux Toolkit)
listenerMiddleware 旨在成為更廣泛使用的 Redux 非同步中間件(例如 sagas 和 observables)的輕量級替代方案。雖然在複雜性和概念層面上類似於 thunk,但它可用於複製一些常見的 saga 使用模式。
listenerMiddleware.startListening({
matcher: isAnyOf(action1, action2, action3),
effect: (action, listenerApi) => {
const user = selectUserDetails(listenerApi.getState())
const { specialData } = action.meta
analyticsApi.trackUsage(action.type, user, specialData)
}
})
redux-saga/redux-saga
使用同步型產生器函式處理非同步邏輯。Sagas 會傳回效應描述,由 saga 中介軟體執行,並充當 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
使用稱為「epics」的 RxJS 可觀察鏈處理非同步邏輯。撰寫並取消非同步動作以建立副作用等。
最適合:複雜的非同步邏輯、解耦的工作流程
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)
將 Elm 架構移植到 Redux,可讓您透過傳回 reducer 中的效應來順暢且純粹地對效應進行排序。Reducer 現在會傳回狀態值和副作用描述。
最適合:在 Redux+JS 中盡可能接近 Elm
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
}
}
使用可觀察物件建立的副作用函式庫,但允許使用回呼、承諾、非同步/等待或可觀察物件。提供動作的宣告式處理。
最適合:高度解耦的非同步邏輯
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)
}
})
Promises
acdlite/redux-promise
將承諾作為動作有效負載傳送,並在承諾解決或拒絕時傳送符合 FSA 的動作。
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
明智、宣告式、基於慣例的承諾處理,在不公開傳送完整權限的情況下引導使用者朝正確方向。
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 }),
});
中介軟體
網路和 Socket
svrcekmichal/redux-axios-middleware
使用 Axios 擷取資料並傳送開始/成功/失敗動作
export const loadCategories() => ({ type: 'LOAD', payload: { request : { url: '/categories'} } });
agraboso/redux-api-middleware
讀取 API 呼叫動作、擷取並傳送 FSA
const fetchUsers = () => ({
[CALL_API]: {
endpoint: 'http://www.example.com/api/users',
method: 'GET',
types: ['REQUEST', 'SUCCESS', 'FAILURE']
}
})
itaylor/redux-socket.io
socket.io 和 redux 之間的意見化連接器。
const store = configureStore({
reducer,
middleware: getDefaultMiddleware =>
getDefaultMiddleware.concat(socketIoMiddleware)
})
store.dispatch({ type: 'server/hello', data: 'Hello!' })
tiberiuc/redux-react-firebase
Firebase、React 和 Redux 之間的整合
非同步行為
rt2zz/redux-action-buffer
將所有動作緩衝到佇列中,直到符合中斷條件為止,此時會釋放佇列
wyze/redux-debounce
Redux 的 FSA 相容中介軟體,用於抑制動作。
mathieudutour/redux-queue-offline
離線時將動作排隊,並在重新連線時傳送動作。
分析
rangle/redux-beacon
與任何分析服務整合,可在離線時追蹤,並將分析邏輯與應用程式邏輯分離
markdalgleish/redux-analytics
監控具有 meta 分析值的 Flux 標準動作,並處理這些動作
實體與集合
tommikaikkonen/redux-orm
一個簡單的不變 ORM,用於管理 Redux 儲存中的關聯資料。
Versent/redux-crud
針對 CRUD 邏輯的慣例動作和簡化器
kwelch/entities-reducer
處理來自 Normalizr 資料的高階簡化器
amplitude/redux-query
與您的元件宣告並置的資料依賴項,在元件掛載時執行查詢,執行樂觀更新,並使用 Redux 動作觸發伺服器變更。
cantierecreativo/redux-bees
規範化資料的宣告式 JSON-API 互動,具有可執行查詢的 React HOC
GetAmbassador/redux-clerk
非同步 CRUD 處理,具有規範化、樂觀更新、同步/非同步動作建立器、選取器和可延伸簡化器。
shoutem/redux-io
具有非同步 CRUD、規範化、樂觀更新、快取、資料狀態和錯誤處理的 JSON-API 抽象。
jmeas/redux-resource
一個用於管理「資源」的微小但強大的系統:儲存在遠端伺服器的資料。
元件狀態和封裝
threepointone/redux-react-local
Redux 中的本地元件狀態,並處理元件動作
@local({
ident: 'counter', initial: 0, reducer : (state, action) => action.me ? state + 1 : state }
})
class Counter extends React.Component {
epeli/lean-redux
讓 Redux 中的元件狀態像 setState 一樣容易
const DynamicCounters = connectLean(
scope: "dynamicCounters",
getInitialState() => ({counterCount : 1}),
addCounter, removeCounter
)(CounterList);
DataDog/redux-doghouse
旨在透過將動作和簡化器限定在元件的特定執行個體中,讓使用 Redux 建立可重複使用的元件變得更容易。
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)
開發工具
偵錯器和檢視器
Dan Abramov 的原始 Redux DevTools 實作,建置於應用程式內顯示狀態和時光旅行偵錯
zalmoxisus/redux-devtools-extension
Mihail Diordiev 的瀏覽器擴充功能,它結合多個狀態監控檢視,並新增與瀏覽器本身開發工具的整合。
一個用於檢查 React 和 React Native 應用程式的跨平台 Electron 應用程式,包括應用程式狀態、API 要求、效能、錯誤、傳奇和動作調度。
DevTools 監控
Log Monitor
具有樹狀檢視的 Redux DevTools 預設監視器
Dock Monitor
可調整大小和移動的 Redux DevTools 監視器 Dock
Slider Monitor
Redux DevTools 的自訂監視器,用於重播已記錄的 Redux 動作
Diff Monitor
Redux DevTools 的監視器,用於比較動作之間的 Redux store 突變
可過濾 Log Monitor
Redux DevTools 的可過濾樹狀檢視監視器
過濾動作
可過濾動作的 Redux DevTools 可組合監視器
記錄
evgenyrodionov/redux-logger
顯示動作、狀態和差異的記錄中介軟體
inakianduaga/redux-state-history
提供時間旅行和高效能動作記錄功能的增強器,包括動作記錄的匯入/匯出和動作播放。
joshwcomeau/redux-vcr
即時記錄和重播使用者階段
socialtables/redux-unhandled-action
在開發中針對未產生狀態變更的動作發出警告
突變偵測
leoasis/redux-immutable-state-invariant
在您嘗試在 dispatch 內部或 dispatch 之間變異狀態時擲回錯誤的中介軟體。
flexport/mutation-sentinel
協助您在執行階段深入偵測突變,並在您的程式碼庫中強制實施不變性。
mmahalwy/redux-pure-connect
檢查並記錄 react-redux 的 connect 方法是否傳遞了建立不純粹 prop 的 mapState
函式。
測試
arnaudbenard/redux-mock-store
儲存已發送動作的模擬 store,以供斷言
Workable/redux-test-belt
擴充 store API,讓斷言、隔離和操作 store 變得更簡單
conorhastings/redux-test-recorder
基於應用程式中的動作自動產生 reducer 測試的中介軟體
wix/redux-testkit
測試 Redux 專案(reducer、selector、action、thunk)的完整且見解獨到的測試套件
jfairbank/redux-saga-test-plan
讓 saga 的整合和單元測試變得輕鬆
路由
supasate/connected-react-router將 React Router v4+ 狀態與 Redux 儲存庫同步。
faceyspacey/redux-first-router
無縫的 Redux-first 路由。將您的應用程式視為狀態,而非路由或元件,同時保持網址列同步。一切都是狀態。連接您的元件並僅傳送 flux 標準動作。
表單
erikras/redux-form
一個功能齊全的函式庫,讓 React HTML 表單可以將其狀態儲存在 Redux 中。
davidkpiano/react-redux-form
React Redux Form 是一組 reducer 建立器和 action 建立器,讓使用 React 和 Redux 實作最複雜和自訂的表單變得簡單且高效能。
更高級別的抽象
keajs/kea
Redux、Redux-Saga 和 Reselect 的抽象。提供應用程式的動作、reducer、selector 和 saga 的架構。它賦能 Redux,讓它像使用 setState 一樣簡單。它減少了樣板和冗餘,同時保留了可組合性。
TheComfyChair/redux-scc
採用已定義的結構並使用「行為」來建立一組動作、reducer 回應和 selector。
Bloomca/redux-tiles
在 Redux 上提供最小的抽象,以允許輕鬆的組合、簡單的非同步請求和健全的可測試性。
社群慣例
Flux 標準動作
Flux 動作物件的人性化標準
正規的 reducer 組合
巢狀 reducer 組合的見解獨到標準
Ducks:Redux reducer 套件
一個用於綑綁 reducer、動作類型和動作的提案