当前位置:网站首页>Redux learning (III) -- using Redux saga, writing middleware functions, and splitting reducer files
Redux learning (III) -- using Redux saga, writing middleware functions, and splitting reducer files
2022-06-11 06:29:00 【Xiaobai learns computer】
One 、redux-devtools
We talked about that before ,redux It is convenient for us to track and debug the state , So how to do it ?
- redux The official website provides us with redux-devtools Tools for ;
- Use this tool , We can know how each state is modified , Status changes before and after modification, etc ;

Installing the tool requires two steps :
- First step : Install the relevant plug-ins in the corresponding browser ( such as Chrome Browser extension store search Redux DevTools that will do , Other methods can refer to GitHub);
- The second step : stay redux In the inheritance devtools Middleware ;

index.js:
import {
createStore, applyMiddleware, compose} from 'redux'
import reducer from "./reducer.js";
import thunkMiddleware from 'redux-thunk'
// composeEnhancers function
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
trace: true}) || compose;
// adopt applyMiddleware To combine multiple Middleware, Return to one storeEnhancer
const storeEnhancer = applyMiddleware(thunkMiddleware)
const store = createStore(reducer, composeEnhancers(storeEnhancer))
export default store;
Two 、generator
saga Middleware uses ES6 Of generator grammar , So we have to explain it briefly :
Be careful : I don't list here generator All uses of , In fact, its usage is very flexible , You can learn by yourself .
Let's follow the steps below to demonstrate the use of the generator :
stay JavaScript Write a common function in , The call will immediately get the return result of this function .
If we write this function as a generator function . call iterator Of next function , Will destroy the iterator once , And return to a yield Result .


Look at the foo The execution order of the generator function code
generator and promise Use it together :
// generator and Promise Use it together
function* bar() {
console.log(111)
const result = yield new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Hello Generator')
}, 3000)
})
console.log(result)
}
const it = bar()
// console.log(it.next().value); // Promise object
it.next().value.then((res) => {
it.next(res)
})
3、 ... and 、redux-saga Use
redux-saga Is another more commonly used in redux Middleware that sends asynchronous requests , Its use is more flexible .
Redux-saga The operation steps are as follows
- install redux-saga
yarn add redux-saga - Integrate redux-saga middleware
Import the function to create the middleware ;
By creating middleware functions , Create middleware , And put it in applyMiddleware Function ;
Start the monitoring process of middleware , And pass in the to be monitored saga;
store/index.js:
import {
createStore, applyMiddleware, compose} from 'redux'
import reducer from "./reducer.js";
import thunkMiddleware from 'redux-thunk'
import createSagaMiddleware from 'redux-saga'
import saga from './saga'
// composeEnhancers function
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
trace: true}) || compose;
// adopt applyMiddleware To combine multiple Middleware, Return to one storeEnhancer
// 1. introduce thunkMiddleware middleware ( The code is on top )
// 2. establish sagaMiddleware middleware
const sagaMiddleware = createSagaMiddleware()
const storeEnhancer = applyMiddleware(thunkMiddleware, sagaMiddleware)
const store = createStore(reducer, composeEnhancers(storeEnhancer))
sagaMiddleware.run(saga) // saga Function for generator
export default store;

3. saga.js Compilation of documents
takeEvery: You can pass in multiple listening actionType, Each can be executed ( There is a corresponding takeLatest, Will cancel the previous )
put: stay saga In the middle action No longer through dispatch, But through put;
all: Can be in yield When put Multiple action;

store/saga.js:
import {
takeEvery, put, all, takeLatest} from 'redux-saga/effects'
import axios from "axios";
import {
FETCH_HOME_MULTIDATA} from "./constants";
import {
changeBannersAction,changeRecommendsAction} from "./actionCreator";
function* fetchHomeMultidata(action) {
const res = yield axios.get('http://123.207.32.32:8000/home/multidata')
const banners = res.data.data.banner.list
const recommends = res.data.data.recommend.list
// yield put(changeBannersAction(banners))
// yield put(changeRecommendsAction(recommends))
yield all([
yield put(changeBannersAction(banners)),
yield put(changeRecommendsAction(recommends))
])
}
function* mySaga() {
// takeEvery: Every action Will be executed
// yield takeEvery(FETCH_HOME_MULTIDATA, fetchHomeMultidata)
// takeLatest: Only one corresponding can be monitored at a time action
// yield takeLatest(FETCH_HOME_MULTIDATA, fetchHomeMultidata)
yield all([
yield takeEvery(FETCH_HOME_MULTIDATA, fetchHomeMultidata)
// yield takeLatest(FETCH_HOME_MULTIDATA, fetchHomeMultidata)
])
}
export default mySaga

home.js:
import React, {
PureComponent} from 'react';
import {
connect} from "react-redux";
import {
addAction,
fetchHomeMultidataAction
}from "../store/actionCreator";
class Home extends PureComponent {
componentDidMount() {
this.props.getHomeMultidata()
}
render() {
return (
<div>
<h1>Home</h1>
<h3> Current count :{
this.props.counter}</h3>
<button onClick={
e => this.props.increment()}>+1</button>
<button onClick={
e => this.props.addNumber(5)}>+5</button>
</div>
);
}
}
const mapStateToProps = state => ({
counter: state.counter
})
const mapDispatchToProps = dispatch => ({
increment() {
dispatch(addAction(1));
},
addNumber(num) {
dispatch(addAction(num));
},
getHomeMultidata() {
dispatch(fetchHomeMultidataAction)
}
})
export default connect(mapStateToProps, mapDispatchToProps)(Home);


Four 、 Print log requirements
As we mentioned earlier , The purpose of middleware is to redux Insert some of your own operations in :
- For example, we now have a demand , stay dispatch Before , Print this action object ,dispatch After that, you can print the latest store
state; - That is, we need to insert the corresponding code into redux Some part of , Let all the after dispatch Can include such operations ;
If there is no middleware , Can we implement similar code ? Relevant printing can be carried out before and after distribution .
But the defect of this method is very obvious :
- First , Every time dispatch operation , We all need to add such logic code to the front ;
- secondly , There's a lot of duplicate code , Will be very cumbersome and bloated ;
Is there a more elegant way to handle this same logic ?
- We can encapsulate the code into a separate function
But such code has a very big flaw :
- caller ( Users ) Using my dispatch when , You must use a function that I encapsulated separately dispatchAndLog;
- obviously , For the caller , It's hard to remember such API, The more common way is to call directly dispatch;



modify dispatch
in fact , We can use a hack A little bit of technology :Monkey Patching, It can be used to modify the original program logic ;
We make the following changes to the code :
- This means that we have directly modified dispatch Call procedure for ;
- Calling dispatch In the process of , The function actually called is dispatchAndLog;
Of course , We can encapsulate it in a module , Just call the function in this module , You can do that. store Do this :
thunk demand
redux-thunk The role of :
We know redux Using a middleware redux-thunk We can make our dispatch No longer just dealing with objects , And can handle functions ; that redux-thunk What is the basic implementation process of ? In fact, it's very simple .
Let's look at the following code :
We are right again dispatch convert , This dispatch Will judge the incoming 
Merge middleware
It is not particularly convenient to call a function to merge middleware , We can encapsulate a function to implement all the middleware merging :
Let's understand the above operation , Code flow :
Of course , The implementation of real middleware will be more flexible , Here we just do a little bit to attract jade , You may refer to it if you are interested redux Merge the source code flow of middleware .
5、 ... and 、Reducer Code splitting
Let's first understand , Why is this function called reducer?
Let's take a look at our current reducer:
- Now this reducer Existing treatment counter Code for , There is also a process home Page data ;
- follow-up counter A related state or home The related states become more complex ;
- We will also continue to add other related states , Like a shopping cart 、 classification 、 Song list, etc ;
- If you put all the states into one reducer Ongoing management , With the increasing scale of the project , Will inevitably cause code bloat 、 Difficult to maintain .
therefore , We can reducer To break up :
- Let's draw a pair first counter To deal with the reducer;
- Draw another pair home To deal with the reducer;
- Combine them ;
6、 ... and 、Reducer File splitting
At present, we have split different state processing into different reducer in , Let's think about :
- Although it has been put into different functions , But the processing of these functions is still in the same file , The code is very confusing ;
- On the other reducer Used in constant、action We are still in the same file ;




7、 ... and 、combineReducers function
At present, the way we merge is through each call reducer The function returns a new object by itself .
in fact ,redux It provides us with a combineReducers Function allows us to easily perform multiple reducer A merger :
that combineReducers How to achieve it ?
in fact , It is also about what we have introduced reducers Merge into one object , Finally return to a combination Function of ( It's the same as before reducer Function );
In execution combination In the process of function , It will determine whether the data returned before and after the return is the same state It's still new state; new state The subscriber will be triggered to refresh , And the old state Can effectively organize subscribers to refresh ;
8、 ... and 、React Medium state How to manage



边栏推荐
- FMT package usage of go and string formatting
- End of 2021 graphics of Shandong University
- Metasploitabile2 target learning
- 572. 另一个树的子树
- JS two methods to determine whether there are duplicate values in the array
- Why don't we have our own programming language?
- About the principle and code implementation of Siou (review IOU, giou, Diou, CIO)
- UEFI finding PCI devices
- Alias the path with the help of craco
- break,continue有什么区别和用法?
猜你喜欢
![Chapter 4 of machine learning [series] naive Bayesian model](/img/77/7720afe4e28cd55284bb365a16ba62.jpg)
Chapter 4 of machine learning [series] naive Bayesian model

PHP laravel8 send email

Why don't we have our own programming language?

What are the differences and usages of break and continue?

100. 相同的树

Make a small game with R language and only basic package

Vulnhub's breach1.0 range exercise

Moment time plug-in tips -js (super detailed)

Résoudre le problème de la durée inexacte du fichier audio AAC obtenu par ffmpeg

Verilog realizes binocular camera image data acquisition and Modelsim simulation, and finally matlab performs image display
随机推荐
autojs,读取一行删除一行,停止自己外的脚本
个人常用软件及浏览器插件分享
021-MongoDB数据库从入门到放弃
JS two methods to determine whether there are duplicate values in the array
Error code in ijkplayer
verilog实现双目摄像头图像数据采集并modelsim仿真,最终matlab进行图像显示
617. 合并二叉树
538.把二叉搜索树转换成累加树
FPGA面試題目筆記(四)—— 序列檢測器、跨時鐘域中的格雷碼、乒乓操作、降低靜動態損耗、定點化無損誤差、恢複時間和移除時間
Docker installation of MySQL and redis
LeetCodeT526
Make a small game with R language and only basic package
fatal: refusing to merge unrelated histories
Handwriting promise [03] - realize multiple calls and chain calls of then method
[reading this article is enough!!! Easy to understand] confidence level understanding (95% confidence level and confidence interval)
Verilog realizes binocular camera image data acquisition and Modelsim simulation, and finally matlab performs image display
Human gene editing technology and ethical issues behind it [personal view, for reference only]
Chapter 6 of machine learning [series] random forest model
CCS安装编译器的方法
Communication between different VLANs