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

react深入2 - react-redux

1.react-redux使用

1.1 安装

npm i redux
npm i react-redux

1.2 创建一个store

// src\store\index.tsimport { createStore, Action } from 'redux';function countReducer(count:number = 0, action:Action) {switch (action.type) {case 'ADD':return count + 1;case 'MINUS':return count - 1;default:return count;}
}export default createStore(countReducer);

1.3 Provider 提供给全局组件使用

// src\main.tsximport React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import ClassPage from './view/ClassPage';function App() {return (<div><Provider store={store}><ClassPage /></Provider></div>);
}render(<App />, document.getElementById('root'));

1.4 子class 组件使用

// src\view\ClassPage.tsximport React, { Component } from 'react';
import { connect } from 'react-redux';// eslint-disable-next-line react/prefer-stateless-function
class ClassPage extends Component {render(): React.ReactNode {console.log(this.props);// eslint-disable-next-line react/prop-typesconst { count, add, minus } = (this.props as any);return (<div><p>{count}</p><button onClick={() => add()} type="button">add</button><button onClick={() => minus()} type="button">minus</button></div>);}
}export default connect((count:number) => ({ count }),(dispatch) => {const add = () => dispatch({ type: 'ADD' });const minus = () => dispatch({ type: 'MINUS' });return {add,minus,dispatch,};},
)(ClassPage);

2.实现自己的 react-redux

// src\react-redux\index.tsximport React, { useContext, useLayoutEffect, useReducer } from 'react';// 创建一个用于存放store的上下文
const Context = React.createContext(undefined);
const StoreProvider = Context.Provider;export function Provider({ store, children }:any) {return <StoreProvider value={store}>{children}</StoreProvider>;
}function useForceUpdate() {const [,forceUpdate] = useReducer((i) => i + 1, 0);return () => forceUpdate();
}
// eslint-disable-next-line max-len
export const connect = (mapStateToProps:any, mapDispatchToProps:any) => (WrappedComponent:any) => (props:any) => {const store = useContext(Context) as any;const forceUpdate = useForceUpdate();const stateProps = mapStateToProps(store.getState());let dispatchProps:any = {};if (typeof mapDispatchToProps === 'function') {dispatchProps = mapDispatchToProps(store.dispatch);} else {// eslint-disable-next-line no-restricted-syntaxfor (const key in mapDispatchToProps) {if (Object.prototype.hasOwnProperty.call(mapDispatchToProps, key)) {dispatchProps[key] = (...args:any) => store.dispatch(mapDispatchToProps[key](...args));}}}useLayoutEffect(() => {const unsubscribe = store.subscribe(() => {forceUpdate();});return () => unsubscribe();}, [forceUpdate, store]);// eslint-disable-next-line react/jsx-props-no-spreadingreturn <WrappedComponent {...props} {...stateProps} {...dispatchProps} />;
};export default {};

3.hook 中使用 react-redux

import React, { useCallback } from 'react';
import { useSelector, useDispatch } from 'react-redux';export default function FunctionPage() {const num = useSelector((count:number) => count);const dispatch = useDispatch();const add = useCallback(() => {dispatch({type: 'ADD',});}, [dispatch]);return (<div><p>{num}</p><button onClick={() => add()} type="button">add</button></div>);
}

4 hooks useSelector useDispatch实现

// src\react-redux\index.tsx// hooks
export function useSelector(selector:any) {const forceUpdate = useForceUpdate();const store = useContext(Context) as any;const selectorState = selector(store.getState());useLayoutEffect(() => {const unsubscribe = store.subscribe(() => {forceUpdate();});return () => unsubscribe();}, [forceUpdate, store]);return selectorState;
}export function useDispatch() {const store = useContext(Context) as any;return store.dispatch;
}

源码

最后编辑于:2025-05-18 10:42:46


喜欢的朋友记得点赞、收藏、关注哦!!!

http://www.xdnf.cn/news/7010.html

相关文章:

  • LangChain框架实战:从入门到开发大模型应用
  • jupyter启动出现OSError: [Errno 28] No space left on device
  • LeetCode算 法 实 战 - - - 双 指 针 与 移 除 元 素、快 慢 指 针 与 删 除 有 序 数 组 中 的 重 复 项
  • 6.2.3+6.2.4十字链表、邻接多重表
  • Nginx配置与命令
  • 数据库中关于查询选课问题的解法
  • Appium自动化测试环境搭建及配置
  • [Linux]安装吧!我的软件包管理器!
  • 怎样免费开发部署自己的网站?
  • Spark 的运行模式(--master) 和 部署方式(--deploy-mode)
  • Linux进程信号(三)之信号产生2
  • Day29 类的装饰器
  • axios的基本使用
  • 网络安全利器:蜜罐技术详解
  • windows11 安装好后右键没有 git bash 命令
  • 【超详细】面试中问到事件循环(Event Loop)机制?
  • 【数据结构】树状数组
  • 基于 STM32 的汽车防盗报警系统设计与实现
  • FPR2100安装ASA镜像
  • 高效查询:位图、B+树
  • 聊一聊契约测试在接口测试中常见的应用场景
  • 互联网大厂Java面试场景:从缓存到容器化的技术问答
  • Spring源码主线全链路拆解:从启动到关闭的完整生命周期
  • 第四章:WebSocket 通信机制全解与客户端发包实录
  • 二十一、案例特训专题4【数据库篇】
  • Vue.js教学第五章:计算属性与侦听器详解
  • 02 K8s双主安装
  • Flink的时间问题
  • 14【高级指南】Django部署最佳实践:从开发到生产的全流程解析
  • JavaScript性能优化实战(12):大型应用性能优化实战案例