redux学习笔记 基础方法1、createStore创建redux的store。支持两种形式createStore(reducer, enchancer)其中reducer为Reducer类型enhancere为StoreEnhancercreateStore(reducer, prelaodedState, enhancer),其中prelaodedState为PreloadedState类型如果enhancer为函数则直接返回enhancer(createStore)(reducer, preloadedState)createStore创建时没有指定enhancer时会分发ActionTypes.INIT返回store对象{dispatch, subscribe, getState, replaceReducer}store对象主要有4个方法dispatch(action: A)根据当前状态以及行为执行currentReducer得到新的状态触发监听器function dispatch(action: A) { if (!isPlainObject(action)) { throw new Error( Actions must be plain objects. Instead, the actual type was: ${kindOf( action )}. You may need to add middleware to your store setup to handle dispatching other values, such as redux-thunk to handle dispatching functions. See https://redux.js.org/tutorials/fundamentals/part-4-store#middleware and https://redux.js.org/tutorials/fundamentals/part-6-async-logic#using-the-redux-thunk-middleware for examples. ) } if (typeof action.type undefined) { throw new Error( Actions may not have an undefined type property. You may have misspelled an action type string constant. ) } if (typeof action.type ! string) { throw new Error( Action type property must be a string. Instead, the actual type was: ${kindOf( action.type )}. Value was: ${String(action.type)} (stringified) ) } if (isDispatching) { throw new Error(Reducers may not dispatch actions.) } try { isDispatching true currentState currentReducer(currentState, action) } finally { isDispatching false } const listeners (currentListeners nextListeners) listeners.forEach(listener { listener() }) return action }subscribe(listener: () void)订阅监听者同时返回取消注册function subscribe(listener: () void) { if (typeof listener ! function) { throw new Error( Expected the listener to be a function. Instead, received: ${kindOf( listener )} ) } if (isDispatching) { throw new Error( You may not call store.subscribe() while the reducer is executing. If you would like to be notified after the store has been updated, subscribe from a component and invoke store.getState() in the callback to access the latest state. See https://redux.js.org/api/store#subscribelistener for more details. ) } let isSubscribed true ensureCanMutateNextListeners() const listenerId listenerIdCounter nextListeners.set(listenerId, listener) return function unsubscribe() { if (!isSubscribed) { return } if (isDispatching) { throw new Error( You may not unsubscribe from a store listener while the reducer is executing. See https://redux.js.org/api/store#subscribelistener for more details. ) } isSubscribed false ensureCanMutateNextListeners() nextListeners.delete(listenerId) currentListeners null } }getState(): S获取当前的状态function getState(): S { if (isDispatching) { throw new Error( You may not call store.getState() while the reducer is executing. The reducer has already received the state as an argument. Pass it down from the top reducer instead of reading it from the store. ) } return currentState as S }replaceReducer(nextReducer: ReducerS, A): void替换reducer重新计算状态function replaceReducer(nextReducer: ReducerS, A): void { if (typeof nextReducer ! function) { throw new Error( Expected the nextReducer to be a function. Instead, received: ${kindOf( nextReducer )} ) } currentReducer nextReducer as unknown as ReducerS, A, PreloadedState // This action has a similar effect to ActionTypes.INIT. // Any reducers that existed in both the new and old rootReducer // will receive the previous state. This effectively populates // the new state tree with any relevant data from the old one. dispatch({ type: ActionTypes.REPLACE } as A) }2、applyMiddleware应用redux的中间件对store作功能增强。其返回StoreEnhancer。其实现为function applyMiddleware(...middlewares) { return (createStore) (reducer, preloadedState) { const store createStore(reducer, preloadedState) const middlewareAPI {getState: store.getState, dispatch: (action, ...args) dispatch(action, ...args)} const chain middlewars.map(middleware middleware(middlewareAPI)) dispatch compose(..chain)(store.dispatch) return {...store, dispatch} } } export default function compose(...funcs: Function[]) { if (funcs.length 0) { // infer the argument type so it is usable in inference down the line return T(arg: T) arg } if (funcs.length 1) { return funcs[0] } return funcs.reduce( (a, b) (...args: any) a(b(...args)) ) }在对middlewars遍历得到chains当中的每一项都是二级函数compose是调用chains顺序是从右到左依次调用3、combineReducers合并Reducer,对多个reducer作统一处理返回函数function combination(state:StateFromReducerMapObjecttypeof reducers, action:AnyAction):stateexport type ReducersMapObjectS any, A extends Action AnyAction { [K in keyof S]: ReducerS[K], A }可以理解为S的key作为ReducersMapObject的keyvalue为Reducer的函数export type StateFromReducersMapObjectM M extends ReducersMapObject ? { [P in keyof M]: M[P] extends Reducerinfer S, any ? S : never } : neverStateFromReducersMapObject添加另一个泛型M约束M如果继承ReducersMapObject则走{ [P in keyof M]: M[P] extends Reducerinfer S, any ? S : never }的逻辑否则就是never。{ [P in keyof M]: M[P] extends Reducerinfer S, any ? S : never }为对象key来自M对象里面也就是ReducersMapObject里面传入的S。key对应的value就是需要判断M[P]是否继承自Reducer否则是never。combineReducers函数实现为finalReducerKeys为reducers的状态的key,finalReducers为key对应的reducer,combination函数遍历reducerKey通过reducer计算得到当前key的状态nextStateForKey,统一放到状态对象nextState中通过状态是否有改变返回nextState或者state。function combination( state: StateFromReducersMapObjecttypeof reducers {}, action: AnyAction ) { let hasChanged false const nextState: StateFromReducersMapObjecttypeof reducers {} for (let i 0; i finalReducerKeys.length; i) { const key finalReducerKeys[i] const reducer finalReducers[key] const previousStateForKey state[key] const nextStateForKey reducer(previousStateForKey, action) nextState[key] nextStateForKey hasChanged hasChanged || nextStateForKey ! previousStateForKey } hasChanged hasChanged || finalReducerKeys.length ! Object.keys(state).length return hasChanged ? nextState : state }4、compose函数组合调用。其实现为function compose(...funcs:Function[]) { if (funcs.length 0) { return (arg) arg } if (funcs.length 1) { return funcs[0] } return funcs.reduce((a, b) (...args) a(b(...args))) }5、 MiddlewareMiddlewareAPI接口包含两个方法dispatch和getStateexport interface MiddlewareAPID extends Dispatch Dispatch, S any { dispatch: D getState: () S }Middleware输入为MiddlewareAPI输出为二级函数其类型定义为,export interface Middleware _DispatchExt {}, // TODO: see if this can be used in type definition somehow (cant be removed, as is used to get final dispatch type) S any, D extends Dispatch Dispatch { ( api: MiddlewareAPID, S ): (next: (action: unknown) unknown) (action: unknown) unknown }redux开源中间件redux-thunkredux-promiseredux-composable-fetchredux-sagareact-router-redux将路由状态纳入redux的状态管理将React Router与Redux store绑定import {browserHistory} from react-router; import {syncHistoryWithStore} from react-router-redux; import reducers from project-path/reducers; const store createStore(reducers); const history syncHistoryWithStore(browserHistory, store);用redux方式改变路由import {browserHistory} from react-router; import {routerMiddleware} from react-router-redux; const middleware routerMiddleware(browserHistory); const store createStore(reducers, applyMiddleware(middleware));

相关新闻

最新新闻

3 种主流遥感图像融合算法对比:PanSharpen、PCA 与小波变换的 PSNR 指标分析

3 种主流遥感图像融合算法对比:PanSharpen、PCA 与小波变换的 PSNR 指标分析

3 种主流遥感图像融合算法对比:PanSharpen、PCA 与小波变换的 PSNR 指标分析遥感图像融合技术是提升影像空间分辨率与光谱保真度的关键手段。本文将深入解析 PanSharpen、主成分分析(PCA)和小波变换三种主流算法的技术原理,并通过…

2026/7/6 22:40:58
OpenRocket:如何用开源软件设计你的第一枚模型火箭?

OpenRocket:如何用开源软件设计你的第一枚模型火箭?

OpenRocket:如何用开源软件设计你的第一枚模型火箭? 【免费下载链接】openrocket Model-rocketry aerodynamics and trajectory simulation software 项目地址: https://gitcode.com/GitHub_Trending/op/openrocket OpenRocket是一款功能完整的开…

2026/7/6 22:40:58
Docker Buildx 实战:在 Windows 11 x86 平台构建 ARM64 镜像的 2 种方案对比

Docker Buildx 实战:在 Windows 11 x86 平台构建 ARM64 镜像的 2 种方案对比

Docker Buildx 实战:在 Windows 11 x86 平台构建 ARM64 镜像的完整指南随着 ARM 架构在服务器领域的普及,越来越多的开发者需要在 x86 平台上为 ARM 设备构建 Docker 镜像。本文将深入探讨在 Windows 11 (x86/amd64) 主机上使用 Docker Desktop 的 Build…

2026/7/6 22:40:58
Paperxie 期刊论文智能写作|科研人问答实录,拆解普刊 / 核心 / SCI 专属写稿神器

Paperxie 期刊论文智能写作|科研人问答实录,拆解普刊 / 核心 / SCI 专属写稿神器

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/期刊论文期刊论文 - PaperXie智能写作PaperXieAi论文智能生成软件,10分钟生成万字毕业论文、期刊论文、文献综述、PPT,Aigc查重、降重报告、文献资料。只需一个标题,从开…

2026/7/6 22:40:58
Snowflake时间旅行实战指南:原理、避坑与高效回滚

Snowflake时间旅行实战指南:原理、避坑与高效回滚

1. 项目概述:时间旅行不是科幻,是Snowflake里每天都在用的“后悔药”在Snowflake上删错一张表、改错一个字段、误删十万行关键订单数据——这种事我干过三次。第一次是刚接手客户数仓时手抖执行了DROP TABLE production_orders;,第二次是ETL脚…

2026/7/6 22:40:58
从实验到实战:基于 Linux 系统调用构建 Hash 文件库的 5 个关键设计

从实验到实战:基于 Linux 系统调用构建 Hash 文件库的 5 个关键设计

从实验到实战:基于 Linux 系统调用构建 Hash 文件库的 5 个关键设计在 Linux 系统编程领域,文件操作是最基础也最核心的技能之一。然而,标准的 Linux 文件系统提供的流式文件接口虽然简洁灵活,却缺乏对随机检索的直接支持。本文将…

2026/7/6 22:35:58

月新闻