大家都知道redux是一个封装好的react集中式数据流管理方案
我们今天来自己通过react hooks的两个钩子函数useContext()、useReducer() 来实现一下redux功能
首先,创建一个全局对象context对象
创建一个存放常量的文件,方便action function和reducer函数根据常量完成不同业务,直接引用,无需多次创建
action function文件
reducer 函数
App组件
import React,{useReducer} from "react";
import {GetEmail} from "./GetEmail";
import {user} from './reducers/user';
import Child from './Child';
//初始state值
const initialState = {
user:null
}
//判断是否是promise对象
function isPromise(obj){
return(
!!obj && (typeof obj==="object"||typeof obj==="function")
&&typeof obj.then ==="function"
);
}
function wrapperDispatch(dispatch){
return function(action){//处理后代传过来的action
if(isPromise(action.payload)){//判断是否是Promise对象
action.payload.then(res=>{//axios请求成功
//发送带数据的action给注册的reducer函数
dispatch({type:action.type,payload:res})
})
}else{//普通action对象直接转发action给注册的reducer函数
dispatch(action);
}
}
}
const App = () => {
//让静态组件拥有state,通过dispatch传递action给reducer函数来改变state
let [state,dispatch] = useReducer(user,initialState);
// 注册的reducer函数 ,初始state
return (
<>
<h3>App组件</h3>
<GetEmail.Provider value={{state,dispatch:wrapperDispatch(dispatch)}} >
//将全局context里面的内容向后代传递
<Child />
</GetEmail.Provider>
</>
);
}
export default App;
Child组件
GrandChild组件
执行流程概括:
首先按照顺序渲染出来
当点击get email按钮时,发送action(调用的是actions function的fetch_user()) 将这个action给App组件的wrapperDispatch,判断是否是异步请求,等异步请求成功获取到数据后,dispatch发送带参数的action给注册好的reducer函数(user.jsx),修改全局state,引发从新render,数据就被刷出来啦!