What is Redux middleware

Middleware allows us to scale redux applications

Middleware is essentially a function

Where do enhancements and extensions come in? This is reflected in the ability to deal with actions. Before, actions were directly processed by reducer, but after the addition of middleware, when actions are triggered by the component, they will be preferentially processed by middleware, and then passed to reducer after the action is processed by middleware. Let the Reducer continue to process the action.

Redux workflow with middleware

Develop Redux middleware

Develop template code for middleware

export default store => next= > action= >{}Copy the code

Middleware only takes effect in the Redux workflow once it is registered after development

import { createStore, applyMiddleware } from 'redux';
import logger from './middleware/logger';

createStore(reducer, applyMiddleaware(logger));
Copy the code

Example of printing action operation logs:

const logger = store= > next= > action= > {
  console.log(action);
  next(action);
}
export default logger;
Copy the code

The intermediate execution order depends on the registration order. Logger is executed first, test is executed, and the reducer is executed.

createStore(reducer, applyMiddleaware(logger, test));
Copy the code

Middleware Development Examples

Thunk middleware allows us to incorporate asynchronous code into Redux workflows

export default store => next= > action= > {
  if (typeof action === 'function') {
    action(store.dispatch);
    return;
  }
  next(action);
}
Copy the code

In this case, asynchronous Action Creator returns a function, which contains asynchronous operations. After the asynchronous operations are completed, dispatch is called to trigger the action to be sent to reducer

export const increment_async = payload= > dispatch= > {
  setTimeout(() = > {
    dispatch(increment(payload))
  }, 2000)}Copy the code

Redux common middleware

redux-thunk

Allows asynchronous operations to be added to redux workflows, similar to the self-implemented Thunk above

  1. download
npm install redux-thunk
Copy the code
  1. Introduce the story – thunk
import thunk from 'redux-thunk';
Copy the code
  1. Registered redux – thunk
import { applyMiddleware } from 'redux';
createStore(rootReduer, applyMiddleware(thubk));
Copy the code
  1. Use the Redux-Thunk middleware
const fetchPosts = () = > async dispatch => {
  const posts = await axios.get('api/posts').then(res= > res.data);
  dispatch({ type: 'FETACHPOSTS'.payload: posts });
}
Copy the code

redux-saga

Redux-saga works the same way as redux-thunk in that it allows asynchronous operations to be added to the Redux workflow. Redux-saga is more powerful than Redux-Thunk.

Problems solved by Redux-Saga

Redux-saga can take asynchronous operations out of the Action Creator file and put them in a separate file.

Story – saga

  1. download
npm install redux-saga
Copy the code
  1. Create the Redux-Saga middleware
import createSagaMiddleware from 'redux-saga';
const sagaMiddleware = createSagaMiddleware();
Copy the code
  1. Registered sagaMiddleware
createStore(reducer, applyMiddleware(sagaMiddleware));
Copy the code
  1. Use saga to receive actions to perform asynchronous operations
import { takeEvery, put, delay } from 'redux-saga/effects; '

function* increment_async_fn () {
  yield delay(2000);
  yield put(increment(10))}export default function* counterSaga () {
  yield takeEvery(INCREMENT_ASYNC, increment_async_fn);
}
Copy the code

TakeEvery is used to receive actions, and PUT is used to trigger another action. When the result of the asynchronous operation is returned, put triggers the action and sends the result of the asynchronous operation to reducer. Ask the reducer to save this data in the store. INCREMENT_ASYNC is the action.type triggered by dispatch in the component and increment is the action Creator passed to the Reducer.

  1. Start the saga
import postSaga form './store/sagas/post/post.saga';

sagaMiddleware.run(postSaga);
Copy the code
  1. The action and transfer

How to pass an action parameter when the component triggers an action?

<button onClick={() = > props.increment_async(20)}>
 +
</button>
Copy the code
function* increment_async_fn (action) {
  yield delay(2000);
  yield put(increment(action.payload));
}
Copy the code
  1. Saga file split and merge
import { all } from 'redux-saga/effects';

import counterSaga from './counter.saga';
import modalSaga from './modal.saga';

export default function* rootSaga () {
  yield all([
    counterSaga(),
    modalSaga()
  ])
}
Copy the code
import createSagaMiddleware from 'redux-saga';
import rootSaga from './sagas/root.saga';

const sagaMiddleware = createSagaMiddleware();
sagaMiddleware.run(rootSaga);
Copy the code

redux-actions

Redux-actions for resolving problems

A lot of boilerplate code reading and writing in the REdux process is a pain, and using Redux-Actions simplifies Action and Reducer processing.

Story – the actions to use

  1. download
npm install redux-actions
Copy the code
  1. Create an Action
import { createAction } from 'redux-actions';

const increment_action = createAction('increment');
const decrement_action = createAction('decrement');
Copy the code

CreateAction helps us generate the Action Creator function

  1. Create the Reducer
import { handleAction as createReducer } from 'redux-actions';
import { increment_action, decrement_action } from '.. /actions/counter.actions';

const initialState = { count: 0 };
const counterReducer = createReducer({
  [increment_action]: (state, action) = > ({ count: state.count + 1 }),
  [decrement_action]: (state, action) = > ({ count: state.count - 1 }),
}, initialState);

export default counterReducer;
Copy the code