当前位置:网站首页>Redux main knowledge learning summary
Redux main knowledge learning summary
2022-07-20 09:49:00 【Yun Qi】
The article comes from a personal blog https://knightyun.github.io/2020/11/29/js-redux-summary, Reprint please state
Concept
Redux As a state manager , It can be applied to a variety of web Technology or framework ,React Just one of them ;Redux It is characterized by , Multiple pages or components use the same state (store, For managing applications state), It can realize data sharing between modules or components , Any part of the application can be modified , It avoids the traditional problem of deep-seated value transfer between components ;
Use
Create a state of (store)
Redux.createStore()
Method is used to create a store
, The receiving reducer
As the first parameter ;
reducer
For a custom function , receive state
As the first parameter , At the same time, return a value as a new state
;
reduce There is a reduction , The meaning of reduction , It can be understood as a reducer , Constantly overwrite the new state with the original state , In order to realize the store
Single status update , Its name is also based on Array
Of .reduce()
It's from the method ;
import Redux from 'redux';
// by state Set the default value
const reducer = (state = 1, action) => {
return state;
}
const store = Redux.createStore(reducer);
createStore()
Method also receives the second parameter initialState
, As state
Is the initialization value of , That is, the following two writing methods have the same effect :
import Redux from 'redux';
const store1 = Redux.createStore((state = 1) => {
return state;
});
const store2 = Redux.createStore((state) => {
return state;
}, 1);
const state1 = store1.getState();
const state2 = store2.getState();
console.log(state1); // 1
console.log(state2); // 1
Read status
getState()
, Is created store
A method of an object , Used to get the created status ;
const store = Redux.createStore(
(state = 1) => state;
);
const state = store.getState();
console.log(state); // 1
Change state (action)
Trigger update
state
The update of needs to be triggered action
To achieve ,actoin
It's in front. reducer
The second parameter that the function receives , One action
Is an object containing operation information , At the same time, it can also carry additional data to be transferred ;
Trigger action
Use dispatch
Realization ,dispatch
yes store
A method of an object , Its receiving parameters are action
object , Is the only way to update the status ;
The reason for adding one more layer here action
, Instead of directly modifying the status , To track why a state is updated , Or operation reproduction during debugging , and action
Medium type
It is equivalent to the trace left in order to be tracked ;
const store = Redux.createStore(
(state=1, action) => {
if (action.type === 'myAction') {
return action.myData;
} else {
return state;
}
}
);
const action = {
type: 'myAction', // type Attribute is required
myData: 'myContent.', // Custom carry data
}
store.dispatch(action);
console.log(store.getState()); // "myContent."
In complex applications with many modules , In order to identify the operation , Easy to understand , Usually type
The format of will be defined as modular / operation
In the form of , modular
General and corresponding reducer
relevant , for example :
const todoReducer = (state, action) => state;
const userReducer = (state, action) => state;
const addTodo = {
type: 'todo/add' };
const renameUser = {
type: 'user/rename' };
Respond to updates
to update state
Of action
Triggered , You also need to define some operations to respond to them , stay action
Execute when triggered , That is, specify how to update state
;
Update here state
The logic of was created before store
When it came in reducer
Function , because Redux Medium state
Is read-only ( It's not mandatory , But you need to follow it in your code ), therefore reducer
Each return state
It's all new ;
const myState = {
num: 0
}
const myReducer = (state=myState, action) => {
if (action.type === 'add') {
return {
num: state.num + 1
};
} else {
return state; // If the status is not specified, you need to consider returning to the original status
}
}
const store = Redux.createStore(myReducer);
const myAction = {
type: 'add'
}
store.dispatch(myAction);
console.log(store.getState().num); // 1
Redux It's not mandatory reducer
Medium state
For read-only , In fact, it can be modified , for example :
const defaultState = {
num: 0 };
const store = Redux.createStore(
(state=defaultState, action) => {
if (action.type === 'add') {
state.num += 1;
return state;
} else {
return state;
}
}
);
console.log(store.getState()); // { num: 0 }
store.dispatch({
type: 'add'});
console.log(store.getState()); // { num: 1 }
But officials do not recommend this , This may lead to page data not being updated in time bug, Therefore, developers need to consider maintaining their own Immutability (Immutability), This also enables better status tracking , Development experience such as problem tracing , An item mentioned on the official website is time traveling debugging
technology ; also ,Redux The introduction of the framework on the official website is also Redux is a predictable state container
, Predictive state manager ;
Subscription Status
subscribe()
yes store One of the methods of object , It takes a function as an argument , Used to set up listeners to subscribe to status updates , Designated state
What should be done when updating ;
const store = Redux.createStore((state=0, action) => {
if (action.type === 'add') {
return state + 1;
} else {
return state;
}
});
store.subscribe(() => {
// Specifies that the current value is printed every time the status is updated
console.log('dispatch', store.getState());
})
store.dispatch({
type: 'add' }); // 'dispatch' 1
store.dispatch({
type: 'add' }); // 'dispatch' 2
expand
State synthesis
although Redux For the convenience of management, set a single store
For all state
Unified management , But the increase of state quantity will make writing more complicated , therefore Redux Object provides a combineReducers()
Method , The division of labor of all statements is different ( Different components 、 Page or sub application ) Of reducer
Merge into a total reducer
;
This method takes an object as a parameter , Different attribute names are used to identify different functions reducer
, And update the status from store
Retrieve the status value , The attribute value is declared reducer
function ;
const calcReducer = (state=1, action) => {
switch (action.type) {
case 'add':
return state + 1;
case 'minus':
return state - 1;
default:
return state;
}
}
const countReducer = (state=0, action) => {
if (action.type === 'add') return state + 1;
else return state;
}
const rootReducer = Redux.combineReducers({
calc: calcReducer,
count: countReducer,
});
const store = Redux.createStore(rootReducer);
console.log(store.getState()); // { calc: 1, count: 0, }
store.dispatch({
type: 'add' });
console.log(store.getState()); // { calc: 2, count: 1 }
combineReducers()
The attribute name specified in the parameter object is used to store this reducer All status values of ;
Enhancer
Redux.createStore()
Method can also receive a third parameter enhancer
, For customization store
Or strengthen its ability ( For example, magic change ), Like change dispatch()
, getState()
, subscribe()
Default behavior of methods such as ;
enhancer
The parameter is a custom function , The receiving Redux.createStore
This method is used as a parameter , And return to a new createStore
Method ;
The following is a dispatch
A simple example of adding functionality :
const myReducer = (state=1, action) => {
if (action.type === 'add') {
return state + 1;
} else {
return state;
}
}
// enhancer Receive a parameter , namely Redux.createStore This method ,
// Used to perform creation store Default behavior of ;
const myEnhancer = (createStore) => {
// enhancer You need to return a function , Its parameters and Redux.createStore In the same ,
// It can be understood as returning another new createStore function ;
return (reducer, initialState, enhancer) => {
// It needs to be carried out once Redux.createStore Default behavior of , And get the store
const store = createStore(reducer, initialState, enhancer);
// modify store Default in dispatch Method
store.dispatch = (action) => {
// New features
console.log('dispatched.');
// Finally, it still needs to be executed once dispatch Default behavior of
return store.dispatch(action);
}
// Modify the default getState Method
store.getState = () => {
return store.getState() + 1;
}
// Back to the new createStore Method also needs to return an object , The whole store object ;
return store;
}
}
}
const store = Redux.createStore(myReducer, undefined, myEnhancer);
store.dispatch({
type: 'add' }); // "dispatched."
console.log(store.getState()); // 3
You need to use multiple enhancer
when , It needs to be synthesized , have access to Redux.compose()
Method :
const enhancers = Redux.compose(enhancer1, enhancer2); // You can pass in multiple parameters for enhancer
const store = Redux.createStore(myReducer, undefined, enhancers);
Middleware
Most of the time , We just want to customize dispatcch
The logic of the method , So the official has provided a special one called middleware
Characteristics of , Which translates as middleware , That is, trigger action
And call reducer
Between execution responses , Provide users with an operable space , For example, it is used for logging , Problem report , Or handle asynchronous operations ;
middleware
It's a custom function , It receives an object as a parameter , This parameter object has two methods , Namely dispatch
and getState
, Logical and store
Two methods with the same name in the object are the same ;
middleware
Function also needs to return another function as a wrapper ( Customize ) After dispatch
Method , Because there are many logical levels , The following will be explained by code ;
Redux There is a built-in one called applyMiddleware
Of enhancer
Method , Used to add middleware
, It can receive multiple parameters to pass in multiple middleware
;
The specific implementation is illustrated by examples :
const myReducer = (state, action) => {
if (action.type === 'add') {
return state + 1;
} else {
return state;
}
}
// Customized middleware functions
const myMiddleware1 = ({
dispatch, getState }) => {
// The middleware needs to return a function , Namely new dispatch Logic ,
// This function receives another parameter next, Used to execute the next middleware,
// Of course, if there is the next middleware, execute , If not, execute the original dispatch,
// In fact, this parameter next That is, the original one store.dispatch Method ;
return (next) => {
// This function also needs to return a function , Used for processing action,
// Receive one acction As a parameter , namely store The trigger action;
return (action) => {
// Custom logic
console.log('mid 1', getState());
// This function also needs to return a function , Use the previous next Method
// take action Pass to next middleware To continue processing ;
return next(action);
}
}
}
// You can also use abbreviations
const myMiddleware2 = ({
getState }) => next => action => {
console.log('mid 2', getState());
const result = next(action);
console.log('mid 2 new', getState());
return result;
}
// Using middleware
const myEnhancer = Redux.applyMiddleware(myMiddleware1, myMiddleware2);
const store = Redux.createStore(myReducer, 1, myEnhancer);
store.dispatch({
type: 'add' });
// "mid 1" 1
// "mid 2" 1
// "mid 2 new" 2
console.log(store.getState());
// 2
To summarize the whole implementation process is :
- The user called
store.dispatch()
Triggeraction
; - Redux Press
applyMiddleware()
Pass in order of parameters in method , Execute customized one by onemiddleware
Logic ; - Then call the original
store.dispatch()
Methods the triggeraction
; - Final execution
reducer
Logic in ;
The whole process is similar to the chain call of functions :
dispatch -> middleware1 -> middleware2 ... -> dispatch -> reducer
Besides , because middleware
Execution logic , Its characteristics also include action
Data modification in 、 Interrupt or even stop completely action
, Trigger , For example, in the above example, it does not return next(action)
, Then the whole process completes the first middleware
It's over ,state
Nor will it change as expected ;
Handle asynchronous logic
Redux Internally, I don't know how to handle asynchronous logic , It will only trigger synchronously action, And then call reducer to update state, So any asynchronous logic needs to be implemented externally by ourselves ; and Redux The purpose of recuder Don't have any side effect , Better be a Pure function , That is, there should be no unnecessary external connections , Such as console printing , Asynchronous request, etc ;
and middleware
Namely Redux Specially designed for side effect Designed for logical requirements , Here, take asynchronous operation as an example, and simply implement it with code :
const reducer = (state, action) => {
if (action.type === 'add') {
return state + 1;
} else if (action.type === 'asyncAdd') {
return action.data;
} else {
return state;
}
}
const asyncMiddleware = _store => next => action => {
if (action.type === 'asyncAdd') {
setTimeout(() => {
action.data = 'some data.';
next(action);
}, 2000);
} else {
next(action);
}
}
const enhancer = Redux.applyMiddleware(asyncMiddleware);
const store = Redux.createStore(reducer, 0, enhancer);
store.dispatch({
type: 'add' });
console.log(store.getState()); // 1
store.dispatch({
type: 'asyncAdd' });
console.log(store.getState()); // 1
setTimeout(() => {
console.log(store.getState());
}, 2000);
// 2 Second output :
// some data.
The result shows the data obtained by asynchronous operation , Can be successfully reducer
Get and implement the corresponding logic , So the setTimeout
Switch to Ajax
The request can also get data from the server , And pass it to Redux Take the next step ;
Because the native writing of asynchronous logic above is not convenient ,Redux The official has provided one redux-thunk
Tools , One is encapsulated middleware
, After application, you can put action
Declared as a function ( It used to be an object ), The receiving dispatch
and getState
Two parameters ; The usage is as follows :
import Redux from 'redux';
import ReduxThunk from 'redux-thunk';
const reducer = (state, action) => {
if (action.type === 'add') {
return state + 1;
} else if (action.type === 'asyncAdd') {
return action.data;
} else {
return state;
}
}
// Apply the tool directly
const middlewareEnhancer = Redux.applyMiddleware(ReduxThunk.default);
const store = Redux.createStore(reducer, 1, middlewareEnhancer);
// here action Declared as a function , Handle asynchronous logic
const asyncAction = (dispatch, getState) => {
console.log('old state:', getState());
setTimeout(() => {
dispatch({
type: 'asyncAdd', data: 'some data.' });
}, 2000);
}
store.dispatch(asyncAction);
// "old state:" 1
setTimeout(() => {
console.log(store.getState());
}, 2000);
// 2 Second output :
// "some data."
need Be careful Yes. , Some tutorials ( Include Redux Official website ) Introduce Redux Thunk
When using , Still in use Redux.applyMiddleware(ReduxThunk)
How to write it , This is the tool 1.x
Version writing , Now? 2.x
The version needs to add .default
, namely Redux.applyMiddleware(ReduxThunk.default)
, Otherwise, the program will have problems ;
边栏推荐
猜你喜欢
一分钟掌握卡诺图化简法
FreeRTOS线程安全、中断安全的printf实现方式
瑞芯微RK3568开发板深度评测
Hard core strength! Feiling Ti Sitara am62x series-335x classic continuation
RTOS——桌面mini网络时钟
Xilinx 7 Series primitive use (clock related) - (I)
[mindspore] [Lite end-to-side training reasoning] mindspore lit runs the lenet training example code according to the instructions and reports an error
[Lora & nb IOT] current situation analysis
线性卷积、循环卷积、周期卷积的定义、计算方法及三者之间的关系
VSFTP服务器搭建
随机推荐
smplify
【DOM】初识DOM
Interpretation of semi supervised contractual learning for label effective medical image segmentation
Centos7x Oracle 11G的rac部署(无图形化安装)
UltraEdit自动换行/制表符设置
Verilog HDL语言总结(全)
Qualcomm snpe
[mindspire] after installation, run the official website test code and report an error
FPGA刷题P4:使用8-3优先编码器实现16-4优先编码器、 使用3-8译码器实现全减器、 实现3-8译码器、使用3-8译码器实现逻辑函数、数据选择器实现逻辑电路
FPGA网口实现与详解(1)
TypeScript 之泛型
硬核实力!飞凌 TI Sitara AM62X 系列-335x经典再续
This paper interprets "PSCL hdeep: image-based protein localization using subcellular prediction integrated in human tissue"
FPGA ——IP核的封装和调用(vivado)
3D HMR correlation
How to use pynative mode for migration learning?
The paper interprets beyond self attention: external attention using two linear layers for visual tasks
stm32f4 PWM捕获 (上升沿/下降沿/高低电平时间)详解(含代码)
【HAL库】串口通信
Mysql45 talking about reading notes in simple terms index (5)