项目作者: retarsis

项目描述 :
🦋 A redux toolkit that tracks your asynchronous redux actions (effects) and informs about the intermediate state using the selector function
高级语言: TypeScript
项目地址: git://github.com/retarsis/redux-pending-effects.git
创建时间: 2020-05-05T18:28:03Z
项目社区:https://github.com/retarsis/redux-pending-effects

开源协议:

下载


Redux Pending Effects

🦋 A redux toolkit that tracks your asynchronous redux actions (effects) and informs about the pending state using the selector function

List of supported libraries that process redux effects:

It’s worth mention that redux-pending-effects allows you to code simultaneously with all libraries above.


Problem it solves

Have you ever been in a situation where you need to add a global loader/spinner to any side effect that your application is processing? Perhaps you are using Redux and some third-party library for asynchronous processing, for example, redux-saga / promise middleware? Great, then it should be interesting to you.

Why not handle the pending state manually for each action?

  • It is very unpleasant to create separately for this state and add start and end actions for these actions to each request.
  • This is an open place to make mistakes because it’s very easy to forget to add or remove these actions.
  • It needs to be supported and somehow live with it.

Well, redux-pending-effects does this from scratch:

  • tracks your asynchronous code
  • collects them in a bunch
  • efficiently calculates active pending effects
  • provides a selector for information about the current state of application loading
  • available for debugging in redux-devtools
  • independent of a particular asynchronous processing solution. Can be used simultaneously with redux-saga and redux-toolkit
  • replaces redux-thunk in the matters of side effects (not actions chaining) and redux-promise-middleware (essentially uses it out of the box)


Quickstart

Installation

```shell script
npm install redux-pending-effects

  1. <br/>
  2. ### Extend reducers
  3. `redux-pending-effects` provides its own state for storing active effects (pending promise phase).
  4. ```javascript
  5. import { combineReducers } from 'redux';
  6. import { includePendingReducer } from 'redux-pending-effects';
  7. import { planetReducer as planet } from './planetReducer';
  8. import { universeReducer as universe } from './universeReducer';
  9. const appReducers = {
  10. planet,
  11. universe
  12. };
  13. const reducersWithPending = includePendingReducer(appReducers);
  14. export const rootReducer = combineReducers(reducersWithPending);


Configuration

The package provides a single entry point for set up via configurePendingEffects

configurePendingEffects accepts a single configuration object parameter, with the following options:

  • promise: boolean (default false) - enable/disable tracking of asynchronous effects that you pass a promise to the payload.
    Yes, if the option enabled, you can pass promise to the payload, that is the way redux-promise-middleware does.
    For details, you can go to read the documentation of redux-promise-middleware
    about how this works.
  • toolkit: boolean (default false) - enable/disable tracking of asynchronous effects produced by redux-toolkit
  • saga: boolean (default false) - enable/disable tracking of asynchronous effects produced by redux-saga
  • ignoredActionTypes: string[] (default []) - list of action types to not track (do not react on actions with these types)

configurePendingEffects returns an object with two properties:

  1. middlewares - an array of defined redux middlewares
  2. sagaOptions - options for createSagaMiddleware in case you intend to use redux-saga


Example

Let’s show an example with all options enabled.

  1. import { configurePendingEffects } from 'redux-pending-effects';
  2. import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
  3. import createSagaMiddleware from '@redux-saga/core';
  4. import { rootReducer as reducer } from './root.reducer';
  5. import { rootSaga } from './root.saga';
  6. const { middlewares, sagaOptions } = configurePendingEffects({
  7. promise: true,
  8. toolkit: true,
  9. saga: true,
  10. ignoredActionTypes: ['IGNORED_ACTION_1', 'IGNORED_ACTION_2']
  11. });
  12. const sagaMiddleware = createSagaMiddleware(sagaOptions);
  13. const toolkitMiddlewares = getDefaultMiddleware();
  14. const middleware = [...middlewares, ...toolkitMiddlewares, sagaMiddleware];
  15. export const store = configureStore({ reducer, middleware });
  16. sagaMiddleware.run(rootSaga);


Selector

Just a regular usage of redux selectors

  1. import React from 'react';
  2. import { useSelector } from 'react-redux';
  3. import { selectIsPending } from 'redux-pending-effects';
  4. import { YourApplication } from './YourApplication';
  5. import { AppLoader } from './App.loader';
  6. export const App = () => {
  7. const isPending = useSelector(selectIsPending);
  8. return isPending ? <AppLoader ></AppLoader> : <YourApplication ></YourApplication>;
  9. };


Notes

At the moment, this library completely replaces redux-promise-middleware.
In the plans, through the collaboration, expand the API of redux-promise-middleware to reuse their internal API.


Contributing

Contributions are welcome. For significant changes, please open an issue first to discuss what you would like to change.

If you made a PR, make sure to update tests as appropriate and keep the examples consistent.


Contact

Please reach me out if you have any questions or comments.


References

I find these packages useful and similar to this one. So, it’s important to mention them here.

The main reason why I didn’t choose them: they do one thing, and it’s impossible to add something second to them.


License

This project is MIT licensed.