当前位置: 首页 > news >正文

React 状态管理

什么是状态管理:
状态管理就是管理应用程序中会变化的数据的一套方法或工具
在react下实现一套状态管理

  1. 组件之外可以共享数据状态
  2. 数据更新,会触发相关方法
  3. 数据更新触发ui更新
    以这几点我们可以基于React框架实现一套自己的状态管理工具
//store.ts
interface Action {type: string,payload?:any
}
const creatData = function (init: any) {let data = init; //初始化数据let deps:Array<Function> = []; //需要订阅的方法function subscribe(fn:Function) {//开始订阅deps.push(fn)return () => {  //取消订阅let index = deps.indexOf(fn);deps.splice(index,1)}}function setDataByAction(action: Action) {const currentData = reducer(data,action) //通过reducer 方法更新状态data = currentData;deps.forEach(fn => fn()) //通知所有订阅者} function getData() {return data}return {subscribe,setDataByAction,getData}
}
const init = {count: 0
}
const reducer = (data:any, action:Action) => {switch(action.type) {case 'add_count':return {count: data.count + 1}case 'change_count':return {count : action.payload}default:return data;}
}
export const objData = creatData(init);

消费阶段

import { objData } from "./store";
const addAction = {type: 'add_count',
}
const changeAction = {type: 'change_count',payload: 100
}
const Button1 = () => {const handleAdd = () => {objData.setDataByAction(addAction)}return <button onClick={handleAdd}></button>;
};
const Button2 = () => {const handleChange = () => {objData.setDataByAction(changeAction)}return <button onClick={handleChange}>修改</button>;
};
const App = () => {const [count, setCount] = useState<number>(0);useEffect(() => {objData.subscribe(() => { //添加监听方法 触发ui更新let data = objData.getData();setCount(data.count);});}, []);return (<div><div>当前数字状态:{count}</div><Button1></Button1><Button2></Button2></div>);
};

这里基本实现了状态管理,其实这也是redux的实现原理,我们继续完善,现在的如果所有的Action全都由同一个reducer方法去管理,基于性能以及可维护性都不好,接下来实现合并reducer

const init = {counter: {count: 0,},info: {name: '张三',age: 16}
}
const counterReducer = (data: any, action: Action) => {console.log(data,action)switch (action.type) {case 'add_count':return { count: data.count + 1 } case 'change_count':return  { count: action.payload } default:return data;}
}
const infoReducer = (data: any, action: Action) => {switch (action.type) {case 'change_age':return  { name: action.payload } case 'change_person':return  { ...action.payload } default:return data;}
}
interface Reducers {counter: Function,info: Function,[key:string]: Function,
}
const combineReducer = function (reducers:Reducers) {return (data: any, action: Action) => { //返回合并后的reducer函数let keys = Object.keys(reducers)const nextState = {} as Reducers; //定义变量存储处理后的datakeys.forEach(key => { //循环执行所有的reducer 合并值let reducerAction = reducers[key]; let cur_state = data[key];const next = reducerAction(cur_state, action)nextState[key] = next})return nextState}
}
const reducer = combineReducer({counter: counterReducer,info: infoReducer
})

这个时候虽然也实现了合并,但是数据的更新我们需要大量的订阅函数以及useState定义,模仿react-redux 结合context实现子组件自动更新

//app.tsx
import myStore from "./store";
const ReduxContext = createContext<null | any>({});
const connect =(mapStateToProps: Function, mapDispatchToProps: Function) =><P extends object>(MyComponent) => {return function ConnectComponent(props: P) {const _store = useContext(ReduxContext);const foceUpdate = () => {setBool(pre => !pre);};useEffect(() => {const unsubscribe = _store.subscribe(() => foceUpdate()); //监听函数,store数据变动强制触发消费store的组件进行更新return () => { //React.StrictMode 模式下必须添加清理函数,否则组件不会触发更新unsubscribe();};}, []);const [, setBool] = useState(false);return (<ReduxContext.Consumer>{store => (<MyComponent{...mapDispatchToProps(store.setDataByAction)}{...mapStateToProps(store.getData())}{...props}/>)}</ReduxContext.Consumer>);};};
const ConnectTest = ({ counter, handleAdd }) => {return (<div><div>当前数字: {counter.count}</div><button onClick={() => handleAdd()}>添加</button></div>);
};
const mapStateToProps = state => {return { counter: state.counter };
};
const mapDispatchToProps = dispatch => {return {handleAdd: () => {console.log("触发更新");dispatch({ type: "add_count" });},};
};
const ConnectCom = connect(mapStateToProps, mapDispatchToProps)(ConnectTest);
const App = () => {return (<ReduxContext.Provider value={myStore}><ConnectCom></ConnectCom></ReduxContext.Provider>);
};

文章转载自:

http://qwMcbaR0.sbczr.cn
http://PpXKk6JX.sbczr.cn
http://KYvbcImh.sbczr.cn
http://5bHlTvLt.sbczr.cn
http://iyyaWynH.sbczr.cn
http://PDhmhk1Z.sbczr.cn
http://Y6Q6z94H.sbczr.cn
http://LhfDPLA8.sbczr.cn
http://agBfDqTQ.sbczr.cn
http://uec4VWKM.sbczr.cn
http://VXDSvvQf.sbczr.cn
http://yvjfiuzE.sbczr.cn
http://UAKnVRq9.sbczr.cn
http://WblA9kPk.sbczr.cn
http://wVeWTSNh.sbczr.cn
http://7HYQSdjt.sbczr.cn
http://JVTF0eJD.sbczr.cn
http://V59EHhCS.sbczr.cn
http://wictZhKd.sbczr.cn
http://DPAYutkl.sbczr.cn
http://1imvMwZy.sbczr.cn
http://Vep71xlD.sbczr.cn
http://fqVAho3R.sbczr.cn
http://RstYv1eE.sbczr.cn
http://5hRydtDr.sbczr.cn
http://u8GfVMwn.sbczr.cn
http://k7TFgR9h.sbczr.cn
http://JolW5FUs.sbczr.cn
http://aTFMDUnd.sbczr.cn
http://WezL6k3e.sbczr.cn
http://www.dtcms.com/a/382957.html

相关文章:

  • [Spring Cloud][5] 注册中心详解,CAP 理论,什么是 Eureka
  • 返利app的跨域问题解决方案:CORS与反向代理在前后端分离架构中的应用
  • C++算法题—图的邻接矩阵输入形式(I\O)
  • 主动性算法-如何让机器拥有嗅觉?
  • Knockout.js Google Closure Compiler 工具模块详解
  • 从关键词匹配到语义理解:6大Embedding技术如何重塑企业搜索
  • 【面试实录01】
  • Docker 容器化部署核心实战——镜像仓库管理与容器多参数运行详解
  • Jenkins的安装与简单使用
  • Step-by-Step:用C语言构建一个带精准错误提示的括号匹配器
  • 【LeetCode - 每日1题】元音拼写检查器
  • KingbaseES读写分离集群架构解析
  • 教育领域大模型生成题目安全研究报告
  • .Net程序员就业现状以及学习路线图(七)
  • uniapp如何使用本身的字体图标
  • Uniapp崩溃监控体系构建:内存泄漏三维定位法(堆栈/资源/线程)
  • window显示驱动开发—显示适配器的子设备
  • 单变量单步时序预测 | TCN-BiGRU时间卷积神经网络结合双向门控循环单元
  • 项目实战——“微商城”前后台【005】之前台项目首页编写
  • 如何利用redis使用一个滑动窗口限流
  • Go与Python/PHP的比较
  • JVM 运行时数据区详解:程序计数器、虚拟机栈、堆内存、方法区与直接内存
  • MongoDB $type 操作符
  • 【靶场练习】--DVWA第一关Brute Force(暴力破解)全难度分析
  • ConcatenationShortcut
  • 设计模式(C++)详解—原型模式(3)
  • 设计模式(C++)详解—原型模式(2)
  • 使用 kubeasz的ezdown部署单节点集群(aio),作为k8s集群的测试环境教程
  • pytest -- 中文文档
  • 数据库造神计划第八天---增删改查(CRUD)(4)