Middleware commonly used at work

redux-thunk

This is the Thunk middleware we implemented, and it works the same way

  1. Download middleware
npm install redux-thunk
Copy the code
  1. Introduce and register middleware
import thunk from 'redux-thunk'

import { applyMiddleware } from 'redux'
export const store = createStore(RootReducer, applyMiddleware(thunk))
Copy the code

Now you can use it happily

redux-saga

Counter delay is implemented with Redux-saga

In line with, but more powerful than, Redux-Thunk, redux-Saga decouple asynchronous operations from the Action Creator file and put them in a separate file, making our project code more maintainable

TakeEvery: Used to receive action, the action type string to receive as the first argument, and the asynchronous method to execute as the second argument

Put: Used to trigger an action consistent with the Dispatch method

We are required to export a generator function by default

  1. Download the story – saga
npm install redux-saga
Copy the code
  1. Create the Redux-Saga middleware
import createSagaMiddleware form 'redux-saga'

const sagaMiddleware = createSagaMiddleware()

createStore(RootReducer, applyMiddleware(sagaMiddleware))
Copy the code
  1. Create an asynchronous action action
export const increment_async = () = > ({type: INCREMENT_ASYNC})
Copy the code
  1. Use saga to intercept actions for asynchronous operations and wait for synchronous changes to be executed after the asynchronous operation completes
import  { takeEvery, put, delay } from 'redux-saga/effects'
import { increment } from '.. /actions/counter.actions'
import { INCREMENT_ASYNC } from '.. /const/counter.const'

function* increment_async_fn () {
    yield delay(2000)
    yield put(increment(10))}export default function* counterSage () {
    yield takeEvery(INCREMENT_ASYNC, increment_async_fn)
}
Copy the code
  1. Start the saga
import createSagaMiddleware from 'redux-saga'
import counterSage from './sagas/counter.sagas'

const sagaMiddleware = createSagaMiddleware()

export const store = createStore(RootReducer, applyMiddleware(sagaMiddleware))

// This method must be executed after createStore
sagaMiddleware.run(counterSage)
Copy the code

Action parameter in redux-saga

  1. Views pass in parameters
<button onClick={() = > increment_async(30)}>+</button>
Copy the code
  1. Accept parameters in the action and add them to the action
export const increment_async = payload= > ({type: INCREMENT_ASYNC, payload})
Copy the code
  1. Parameters are received in the Saga middleware and passed to the action that performs the change action
function* increment_async_fn (action) {
    console.log(action)
    yield delay(2000)
    yield put(increment(action.payload))
}
Copy the code

Saga file split and merge

Use saga to delay showing and hiding pop-up cases

  1. Create an asynchronous action and define action.type as a constant
export const show_async = () = > ({type: SHOWMODAL_ASYNC})

// Define constants
export const SHOWMODAL_ASYNC = 'showModal_async'
Copy the code
  1. Intercept asynchronous aciton in Saga and trigger synchronous change action after performing asynchronous operation
import  { takeEvery, put, delay } from 'redux-saga/effects'
import { show } from '.. /actions/modal.actions'
import { SHOWMODAL_ASYNC } from '.. /const/modal.const'
function* showModal_async_fn (){
    yield delay(2000)
    yield put(show())
}
export default function* counterSage () {
    yield takeEvery(SHOWMODAL_ASYNC, showModal_async_fn)
}
Copy the code
  1. View to trigger an asynchronous action
// function Modal ({ show_async }) {} <button onClick={show_async}> display </button>Copy the code

We found that the saga file received both the asynchronous action of the pop-up box and the asynchronous action of the counter. After too many asynchronous operations, the code became bloated and could not be maintained, so we needed to split and merge the saga

Merger of saga

We need to merge saga using the all method, which takes an array of arguments whose members are the calls to our separate saga

  1. Create the SRC/store/sagas/modal. Sagas. Js file, the code of the pop-up box to the current file
import  { takeEvery, put, delay } from 'redux-saga/effects'
import { show } from '.. /actions/modal.actions'
import { SHOWMODAL_ASYNC } from '.. /const/modal.const'

function* showModal_async_fn (){
    yield delay(2000)
    yield put(show())
}

export default function* modalSaga (){
    yield takeEvery(SHOWMODAL_ASYNC, showModal_async_fn)
}
Copy the code
  1. Create a SRC/store/sagas/root. Saga. Js file, import to create the saga of file merge together
import { all } from 'redux-saga/effects'
import counterSaga from './counter.sagas'
import modalSaga from './modal.sagas'


export default function* rootSaga() {
    yield all([
        counterSaga(),
        modalSaga()
    ])
}
Copy the code
  1. Changed the run saga pass to Rootsaga
import rootSaga from './sagas/root.saga'

const sagaMiddleware = createSagaMiddleware()



export const store = createStore(RootReducer, applyMiddleware(sagaMiddleware))

// This method must be executed after createStore
sagaMiddleware.run(rootSaga)
Copy the code

Story – the actions middleware

Redux-actions helped simplify the action code and reducer code,

A large amount of boilerplate code reading and writing in the REdux process is very painful. Using Redux-Actions can simplify the processing of aciton and Reducer

Download the story – the actions

npm install redux-actions
Copy the code

Create an action

CreateAction takes a string as an argument. This string is the type value in the action object. The return value is self-defined

The actionCreate function triggers and receives the action using the return value of createAction. We don’t need to set type to a constant

import { createAction } from 'redux-actions'

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

Create the reducer

CreateReducer takes two arguments. The first argument is an object. The key of the object is the action created with createAction and the value of the object is the action executed

The second parameter is the initial value

import { handleActions as createReducer } from 'redux-actions'
import { increment_action, decrement_action} from '.. /actions/counter.action'

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

Use redux-Actions to implement counter cases

  1. Create an action with redux-Actions
import { createAction } from 'redux-actions'

export const increment = createAction('increment')
export const decrement = createAction('decrement')
Copy the code
  1. Create the reducer with redux-Actions
import { increment, decrement } from '. /.. /actions/counter.actions'
import { handleActions as createReducer } from 'redux-actions'

const initialState = {
    count: 0
}

const handIncrement = (state, action) = >({count: state.count + 1})
const handDecrement = (state, action) = >({count: state.count - 1})

export default createReducer({
    [increment]: handIncrement,
    [decrement]: handDecrement
}, initialState)
Copy the code
  1. The transfer parameters are passed in the view and received directly from the Reducer
/ / view
function Count({count,increment,decrement}) {
    return <div>
        <button onClick={()= > increment(10)}>+</button>
        <span>{count}</span>
        <button onClick={()= > decrement(20)}>-</button>
    </div>
}

/ / in the reducer
const handIncrement = (state, action) = >({count: state.count + action.payload})
const handDecrement = (state, action) = >({count: state.count - action.payload})
Copy the code

The original address: https://kspf.xyz/archives/22/