生态

Redux 是一个很小的库,但是它的设计和 API 都是经过精心选择的,以至于衍生出工具和扩展的生态系统,并且社区中存在各种各样有用的插件、库和工具。虽然你无需使用任何这些插件即可使用Redux,但它们可以帮助您更轻松地实现功能并解决应用程序中的问题。

有关与Redux相关的库,附加组件和工具的广泛目录 访问 Redux Ecosystem Links 了解更全面的 Redux 库、插件、和工具的目录。此外,React/Redux Links 包含了学习 React 或 Redux 的教程和其他有用资料。

此页面列出了 Redux 维护人员亲自审核的或与社区相关的 Redux 相关插件。不要让这种方法阻止您尝试其余的方法!生态系统增长太快,我们只有有限的时间来无法看到所有内容。考虑这些是“内部人员挑选”,如果您使用 Redux 构建了一些很棒的东西,请毫不犹豫地提交 PR。

目录

与其他框架绑定

reduxjs/react-redux
The official React bindings for Redux, maintained by the Redux team

angular-redux/ng-redux
Angular 1 bindings for Redux

ember-redux/ember-redux
Ember bindings for Redux

glimmer-redux/glimmer-redux
Redux bindings for Ember’s Glimmer component engine

tur-nr/polymer-redux
Redux bindings for Polymer

lastmjs/redux-store-element Redux bindings for custom elements

Reducers

Reducer Combination

ryo33/combineSectionReducers
An expanded version of combineReducers, which allows passing state as a third argument to all slice reducers.

KodersLab/topologically-combine-reducers
A combineReducers variation that allows defining cross-slice dependencies for ordering and data passing

  1. var masterReducer = topologicallyCombineReducers(
  2. { auth, users, todos },
  3. // define the dependency tree
  4. { auth: ['users'], todos: ['auth'] }
  5. )

Reducer Composition

acdlite/reduce-reducers
Provides sequential composition of reducers at the same level

  1. const combinedReducer = combineReducers({ users, posts, comments })
  2. const rootReducer = reduceReducers(combinedReducer, otherTopLevelFeatureReducer)

mhelmer/redux-xforms
A collection of composable reducer transformers

  1. const createByFilter = (predicate, mapActionToKey) =>
  2. compose(
  3. withInitialState({}), // inject initial state as {}
  4. withFilter(predicate), // let through if action has filterName
  5. updateSlice(mapActionToKey), // update a single key in the state
  6. isolateSlice(mapActionToKey) // run the reducer on a single state slice
  7. )

adrienjt/redux-data-structures
Reducer factory functions for common data structures: counters, maps, lists (queues, stacks), sets

  1. const myCounter = counter({
  2. incrementActionTypes: ['INCREMENT'],
  3. decrementActionTypes: ['DECREMENT']
  4. })

高阶 Reducers

omnidan/redux-undo
Effortless undo/redo and action history for your reducers

omnidan/redux-ignore
Ignore redux actions by array or filter function

omnidan/redux-recycle
Reset the redux state on certain actions

ForbesLindesay/redux-optimist
A reducer enhancer to enable type-agnostic optimistic updates

Actions

reduxactions/redux-actions
Flux Standard Action utilities for Redux

  1. const increment = createAction('INCREMENT')
  2. const reducer = handleActions({ [increment]: (state, action) => state + 1 }, 0)
  3. const store = createStore(reducer)
  4. store.dispatch(increment())

BerkeleyTrue/redux-create-types
Creates standard and async action types based on namespaces

  1. export const types = createTypes(
  2. ['openModal', createAsyncTypes('fetch')],
  3. 'app'
  4. )
  5. // { openModal : "app.openModal", fetch : { start : "app.fetch.start", complete: 'app.fetch.complete' } }

maxhallinan/kreighter
Generates action creators based on types and expected fields

  1. const formatTitle = (id, title) => ({
  2. id,
  3. title: toTitleCase(title)
  4. })
  5. const updateBazTitle = fromType('UPDATE_BAZ_TITLE', formatTitle)
  6. updateBazTitle(1, 'foo bar baz')
  7. // -> { type: 'UPDATE_BAZ_TITLE', id: 1, title: 'Foo Bar Baz', }

Utilities

reduxjs/reselect
Creates composable memoized selector functions for efficiently deriving data from the store state

  1. const taxSelector = createSelector(
  2. [subtotalSelector, taxPercentSelector],
  3. (subtotal, taxPercent) => subtotal * (taxPercent / 100)
  4. )

paularmstrong/normalizr
Normalizes nested JSON according to a schema

  1. const user = new schema.Entity('users')
  2. const comment = new schema.Entity('comments', { commenter: user })
  3. const article = new schema.Entity('articles', {
  4. author: user,
  5. comments: [comment]
  6. })
  7. const normalizedData = normalize(originalData, article)

planttheidea/selectorator
Abstractions over Reselect for common selector use cases

  1. const getBarBaz = createSelector(
  2. ['foo.bar', 'baz'],
  3. (bar, baz) => `${bar} ${baz}`
  4. )
  5. getBarBaz({ foo: { bar: 'a' }, baz: 'b' }) // "a b"

Store

Change Subscriptions

jprichardson/redux-watch
Watch for state changes based on key paths or selectors

  1. let w = watch(() => mySelector(store.getState()))
  2. store.subscribe(
  3. w((newVal, oldVal) => {
  4. console.log(newval, oldVal)
  5. })
  6. )

ashaffer/redux-subscribe
Centralized subscriptions to state changes based on paths

  1. store.dispatch( subscribe("users.byId.abcd", "subscription1", () => {} );

Batching

tappleby/redux-batched-subscribe
Store enhancer that can debounce subscription notifications

  1. const debounceNotify = _.debounce(notify => notify())
  2. const store = createStore(
  3. reducer,
  4. initialState,
  5. batchedSubscribe(debounceNotify)
  6. )

manaflair/redux-batch
Store enhancer that allows dispatching arrays of actions

  1. const store = createStore(reducer, reduxBatch)
  2. store.dispatch([{ type: 'INCREMENT' }, { type: 'INCREMENT' }])

laysent/redux-batch-actions-enhancer
Store enhancer that accepts batched actions

  1. const store = createStore(reducer, initialState, batch().enhancer)
  2. store.dispatch(createAction({ type: 'INCREMENT' }, { type: 'INCREMENT' }))

tshelburne/redux-batched-actions
Higher-order reducer that handles batched actions

  1. const store = createStore(enableBatching(reducer), initialState)
  2. store.dispatch(batchActions([{ type: 'INCREMENT' }, { type: 'INCREMENT' }]))

Persistence

rt2zz/redux-persist
Persist and rehydrate a Redux store, with many extensible options

  1. const store = createStore(reducer, autoRehydrate())
  2. persistStore(store)

react-stack/redux-storage
Persistence layer for Redux with flexible backends

  1. const reducer = storage.reducer(combineReducers(reducers))
  2. const engine = createEngineLocalStorage('my-save-key')
  3. const storageMiddleware = storage.createMiddleware(engine)
  4. const store = createStore(reducer, applyMiddleware(storageMiddleware))

redux-offline/redux-offline
Persistent store for Offline-First apps, with support for optimistic UIs

  1. const store = createStore(reducer, offline(offlineConfig))
  2. store.dispatch({
  3. type: 'FOLLOW_USER_REQUEST',
  4. meta: { offline: { effect: {}, commit: {}, rollback: {} } }
  5. })

Immutable Data

ImmerJS/immer
Immutable updates with normal mutative code, using Proxies

  1. const nextState = produce(baseState, draftState => {
  2. draftState.push({ todo: 'Tweet about it' })
  3. draftState[1].done = true
  4. })

副作用

广泛使用

gaearon/redux-thunk
Dispatch functions, which are called and given dispatch and getState as parameters. This acts as a loophole for AJAX calls and other async behavior.

Best for: getting started, simple async and complex synchronous logic.

  1. function fetchData(someValue) {
  2. return (dispatch, getState) => {
  3. dispatch({type : "REQUEST_STARTED"});
  4. myAjaxLib.post("/someEndpoint", {data : someValue})
  5. .then(response => dispatch({type : "REQUEST_SUCCEEDED", payload : response})
  6. .catch(error => dispatch({type : "REQUEST_FAILED", error : error});
  7. };
  8. }
  9. function addTodosIfAllowed(todoText) {
  10. return (dispatch, getState) => {
  11. const state = getState();
  12. if(state.todos.length < MAX_TODOS) {
  13. dispatch({type : "ADD_TODO", text : todoText});
  14. }
  15. }
  16. }

redux-saga/redux-saga
Handle async logic using synchronous-looking generator functions. Sagas return descriptions of effects, which are executed by the saga middleware, and act like “background threads” for JS applications.

Best for: complex async logic, decoupled workflows

  1. function* fetchData(action) {
  2. const { someValue } = action
  3. try {
  4. const response = yield call(myAjaxLib.post, '/someEndpoint', {
  5. data: someValue
  6. })
  7. yield put({ type: 'REQUEST_SUCCEEDED', payload: response })
  8. } catch (error) {
  9. yield put({ type: 'REQUEST_FAILED', error: error })
  10. }
  11. }
  12. function* addTodosIfAllowed(action) {
  13. const { todoText } = action
  14. const todos = yield select(state => state.todos)
  15. if (todos.length < MAX_TODOS) {
  16. yield put({ type: 'ADD_TODO', text: todoText })
  17. }
  18. }

redux-observable/redux-observable

Handle async logic using RxJS observable chains called “epics”. Compose and cancel async actions to create side effects and more.

Best for: complex async logic, decoupled workflows

  1. const loginRequestEpic = action$ =>
  2. action$
  3. .ofType(LOGIN_REQUEST)
  4. .mergeMap(({ payload: { username, password } }) =>
  5. Observable.from(postLogin(username, password))
  6. .map(loginSuccess)
  7. .catch(loginFailure)
  8. )
  9. const loginSuccessfulEpic = action$ =>
  10. action$
  11. .ofType(LOGIN_SUCCESS)
  12. .delay(2000)
  13. .mergeMap(({ payload: { msg } }) => showMessage(msg))
  14. const rootEpic = combineEpics(loginRequestEpic, loginSuccessfulEpic)

redux-loop/redux-loop

A port of the Elm Architecture to Redux that allows you to sequence your effects naturally and purely by returning them from your reducers. Reducers now return both a state value and a side effect description.

Best for: trying to be as much like Elm as possible in Redux+JS

  1. export const reducer = (state = {}, action) => {
  2. switch (action.type) {
  3. case ActionType.LOGIN_REQUEST:
  4. const { username, password } = action.payload
  5. return loop(
  6. { pending: true },
  7. Effect.promise(loginPromise, username, password)
  8. )
  9. case ActionType.LOGIN_SUCCESS:
  10. const { user, msg } = action.payload
  11. return loop(
  12. { pending: false, user },
  13. Effect.promise(delayMessagePromise, msg, 2000)
  14. )
  15. case ActionType.LOGIN_FAILURE:
  16. return { pending: false, err: action.payload }
  17. default:
  18. return state
  19. }
  20. }

jeffbski/redux-logic

Side effects lib built with observables, but allows use of callbacks, promises, async/await, or observables. Provides declarative processing of actions.

Best for: very decoupled async logic

  1. const loginLogic = createLogic({
  2. type: Actions.LOGIN_REQUEST,
  3. process({ getState, action }, dispatch, done) {
  4. const { username, password } = action.payload
  5. postLogin(username, password)
  6. .then(
  7. ({ user, msg }) => {
  8. dispatch(loginSucceeded(user))
  9. setTimeout(() => dispatch(showMessage(msg)), 2000)
  10. },
  11. err => dispatch(loginFailure(err))
  12. )
  13. .then(done)
  14. }
  15. })

Promises

acdlite/redux-promise
Dispatch promises as action payloads, and have FSA-compliant actions dispatched as the promise resolves or rejects.

  1. dispatch({ type: 'FETCH_DATA', payload: myAjaxLib.get('/data') })
  2. // will dispatch either {type : "FETCH_DATA", payload : response} if resolved,
  3. // or dispatch {type : "FETCH_DATA", payload : error, error : true} if rejected

lelandrichardson/redux-pack
Sensible, declarative, convention-based promise handling that guides users in a good direction without exposing the full power of dispatch.

  1. dispatch({type : "FETCH_DATA", payload : myAjaxLib.get("/data") });
  2. // in a reducer:
  3. case "FETCH_DATA": =
  4. return handle(state, action, {
  5. start: prevState => ({
  6. ...prevState,
  7. isLoading: true,
  8. fooError: null
  9. }),
  10. finish: prevState => ({ ...prevState, isLoading: false }),
  11. failure: prevState => ({ ...prevState, fooError: payload }),
  12. success: prevState => ({ ...prevState, foo: payload }),
  13. });

Middleware

网络请求

svrcekmichal/redux-axios-middleware
Fetches data with Axios and dispatches start/success/fail actions

  1. export const loadCategories() => ({ type: 'LOAD', payload: { request : { url: '/categories'} } });

agraboso/redux-api-middleware
Reads API call actions, fetches, and dispatches FSAs

  1. const fetchUsers = () => ({
  2. [CALL_API]: {
  3. endpoint: 'http://www.example.com/api/users',
  4. method: 'GET',
  5. types: ['REQUEST', 'SUCCESS', 'FAILURE']
  6. }
  7. })

itaylor/redux-socket.io
An opinionated connector between socket.io and redux.

  1. const store = createStore(reducer, applyMiddleware(socketIoMiddleware))
  2. store.dispatch({ type: 'server/hello', data: 'Hello!' })

tiberiuc/redux-react-firebase
Integration between Firebase, React, and Redux

异步操作

rt2zz/redux-action-buffer
Buffers all actions into a queue until a breaker condition is met, at which point the queue is released

wyze/redux-debounce
FSA-compliant middleware for Redux to debounce actions.

mathieudutour/redux-queue-offline
Queue actions when offline and dispatch them when getting back online.

分析

rangle/redux-beacon
Integrates with any analytics services, can track while offline, and decouples analytics logic from app logic

markdalgleish/redux-analytics
Watches for Flux Standard Actions with meta analytics values and processes them

实体与集合

tommikaikkonen/redux-orm
A simple immutable ORM to manage relational data in your Redux store.

Versent/redux-crud
Convention-based actions and reducers for CRUD logic

kwelch/entities-reducer
A higher-order reducer that handles data from Normalizr

amplitude/redux-query
Declare colocated data dependencies with your components, run queries when components mount, perform optimistic updates, and trigger server changes with Redux actions.

cantierecreativo/redux-bees
Declarative JSON-API interaction that normalizes data, with a React HOC that can run queries

GetAmbassador/redux-clerk
Async CRUD handling with normalization, optimistic updates, sync/async action creators, selectors, and an extendable reducer.

shoutem/redux-io
JSON-API abstraction with async CRUD, normalization, optimistic updates, caching, data status, and error handling.

jmeas/redux-resource
A tiny but powerful system for managing ‘resources’: data that is persisted to remote servers.

组件 State 与封装

threepointone/redux-react-local
Local component state in Redux, with handling for component actions

  1. @local({
  2. ident: 'counter', initial: 0, reducer : (state, action) => action.me ? state + 1 : state }
  3. })
  4. class Counter extends React.Component {

epeli/lean-redux
Makes component state in Redux as easy as setState

  1. const DynamicCounters = connectLean(
  2. scope: "dynamicCounters",
  3. getInitialState() => ({counterCount : 1}),
  4. addCounter, removeCounter
  5. )(CounterList);

DataDog/redux-doghouse
Aims to make reusable components easier to build with Redux by scoping actions and reducers to a particular instance of a component.

  1. const scopeableActions = new ScopedActionFactory(actionCreators)
  2. const actionCreatorsScopedToA = scopeableActions.scope('a')
  3. actionCreatorsScopedToA.foo('bar') //{ type: SET_FOO, value: 'bar', scopeID: 'a' }
  4. const boundScopeableActions = bindScopedActionFactories(
  5. scopeableActions,
  6. store.dispatch
  7. )
  8. const scopedReducers = scopeReducers(reducers)

开发者工具

Debuggers and Viewers

reduxjs/redux-devtools

Dan Abramov’s original Redux DevTools implementation, built for in-app display of state and time-travel debugging

zalmoxisus/redux-devtools-extension

Mihail Diordiev’s browser extension, which bundles multiple state monitor views and adds integration with the browser’s own 开发者工具

infinitered/reactotron

A cross-platform Electron app for inspecting React and React Native apps, including app state, API requests, perf, errors, sagas, and action dispatching.

开发者工具监听器

Log Monitor
The default monitor for Redux DevTools with a tree view

Dock Monitor
A resizable and movable dock for Redux 开发者工具监听器

Slider Monitor
A custom monitor for Redux DevTools to replay recorded Redux actions

Diff Monitor
A monitor for Redux DevTools that diffs the Redux store mutations between actions

Filterable Log Monitor
Filterable tree view monitor for Redux DevTools

Filter Actions
Redux DevTools composable monitor with the ability to filter actions

日志

evgenyrodionov/redux-logger
Logging middleware that shows actions, states, and diffs

inakianduaga/redux-state-history
Enhancer that provides time-travel and efficient action recording capabilities, including import/export of action logs and action playback.

joshwcomeau/redux-vcr
Record and replay user sessions in real-time

socialtables/redux-unhandled-action
Warns about actions that produced no state changes in development

变更检测

leoasis/redux-immutable-state-invariant
Middleware that throws an error when you try to mutate your state either inside a dispatch or between dispatches.

flexport/mutation-sentinel
Helps you deeply detect mutations at runtime and enforce immutability in your codebase.

mmahalwy/redux-pure-connect
Check and log whether react-redux’s connect method is passed mapState functions that create impure props.

测试

arnaudbenard/redux-mock-store
A mock store that saves dispatched actions in an array for assertions

Workable/redux-test-belt
Extends the store API to make it easier assert, isolate, and manipulate the store

conorhastings/redux-test-recorder
Middleware to automatically generate reducers tests based on actions in the app

wix/redux-testkit
Complete and opinionated testkit for testing Redux projects (reducers, selectors, actions, thunks)

jfairbank/redux-saga-test-plan
Makes integration and unit testing of sagas a breeze

路由

supasate/connected-react-router Synchronize React Router 4 state with your Redux store.

faceyspacey/redux-first-router
Seamless Redux-first routing. Think of your app in states, not routes, not components, while keeping the address bar in sync. Everything is state. Connect your components and just dispatch flux standard actions.

表单

erikras/redux-form
A full-featured library to enable a React HTML form to store its state in Redux.

davidkpiano/react-redux-form
React Redux Form is a collection of reducer creators and action creators that make implementing even the most complex and custom forms with React and Redux simple and performant.

高阶抽象

keajs/kea
An abstraction over Redux, Redux-Saga and Reselect. Provides a framework for your app’s actions, reducers, selectors and sagas. It empowers Redux, making it as simple to use as setState. It reduces boilerplate and redundancy, while retaining composability.

TheComfyChair/redux-scc
Takes a defined structure and uses ‘behaviors’ to create a set of actions, reducer responses and selectors.

Bloomca/redux-tiles
Provides minimal abstraction on top of Redux, to allow easy composability, easy async requests, and sane testability.

社区约定模式

Flux Standard Action
Flux 中 action object 的人性化标准

Canonical Reducer Composition
嵌套 reducer 组成的武断标准

Ducks: Redux Reducer Bundles
关于捆绑多个 reducer, action 类型 和 action 的提案