Middleware commonly used at work
redux-thunk
This is the Thunk middleware we implemented, and it works the same way
- Download middleware
npm install redux-thunk
Copy the code
- 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
- Download the story – saga
npm install redux-saga
Copy the code
- Create the Redux-Saga middleware
import createSagaMiddleware form 'redux-saga'
const sagaMiddleware = createSagaMiddleware()
createStore(RootReducer, applyMiddleware(sagaMiddleware))
Copy the code
- Create an asynchronous action action
export const increment_async = () = > ({type: INCREMENT_ASYNC})
Copy the code
- 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
- 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
- Views pass in parameters
<button onClick={() = > increment_async(30)}>+</button>
Copy the code
- Accept parameters in the action and add them to the action
export const increment_async = payload= > ({type: INCREMENT_ASYNC, payload})
Copy the code
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- Create an action with redux-Actions
import { createAction } from 'redux-actions'
export const increment = createAction('increment')
export const decrement = createAction('decrement')
Copy the code
- 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
- 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/