总体流程:
- 与vue不同,react的数据管理需要自己独立定义store,reducer,action,如果要支持异步,需引入thunk
- store相当于全局变量,需接收reducer变量, (?可能自动处理state数据的订阅及分发?)
- reducer相当于封装对state数据的逻辑处理,
注意不可直接操作state,需返回新的state变量 - action是一个业务处理判断所需的obj数据,或者是一个接收dispatch作为参数的函数
1.首先安装
redux(核心)react-redux(引入hook支持)redux-thunk(支持异步函数)
npm install redux react-redux redux-thunk
2.配置store入口
// store/index.ts
import { applyMiddleware, legacy_createStore } from 'redux'
import reducer from './reducer'
import reduxThunk from 'redux-thunk';
const store = legacy_createStore(reducer,applyMiddleware(reduxThunk))
export default store
2-2.react入口根组件注入store
// 根组件要使用Provider注入store
<Provider store= {store}>
<App />
</Provider>
3.配置reducer, 主要是对state数据的逻辑处理业务
// reducer.ts
const initalState = {
age: 18
}
export default (state = initalState, action) => {
switch(action.type){
case 'addnum': {
let newState = {...state, age: state.age + 1}
return newState
};
default : return initalState;
}
}
4.触发state数据的改变,使用useDispatch分发事件,需传递action
import React from 'react';
import { Button } from 'antd';
import { useDispatch } from 'react-redux';
import { getAsyncDispatch } from './reducer.ts'
function Profile() {
//定义store的分发事件, dispatch 参数可以直接传递action对象
const dispatch = useDispatch
const clickAdd = () => {
// action类型一般默认为{type: string, value?: any}
dispatch({type: 'addnum'})
}
// 模拟异步等待函数
const wait = async (s: number) => {
return new Promise((resolve, reject) => {setTimeout(() => {resolve(s)}, s * 1000)})
}
// 当action是函数时,其自动接收dispatch作为参数传递给内部使用
const getAsyncDispatch = () => {
return async (dispatch: any) => {
let nn = await wait(3)
dispatch({type: 'addnum'})
}
}
const clickAdd2 = () => {
// 当使用thunk后 action可以是一个函数
dispatch(getAsyncDispatch() as any)
}
return (
<Button type="primary" onClick={ clickAdd2 } >数字加一</Button>
)
}
5.其他任意组件展示数据,使用useSelector获取数据,相当于订阅hook
import React from 'react';
import { Button } from 'antd';
import { useSelector } from 'react-redux';
const Userinfo: React.FC = () => {
// 动态获取store的数据
const age = useSelector((state: any) => state.age)
return(
<Button type="text">年龄{age}</Button>
)
}
export default Userinfo;
6.上面只是简单使用示例,正式开发应该会抽离action成单独文件里的函数,或者后续更新toolkit用法