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));

相关新闻

最新新闻

大疆Pocket 4P D-LOG2灰片调色实战:6款定制LUT快速提升Vlog电影感

大疆Pocket 4P D-LOG2灰片调色实战:6款定制LUT快速提升Vlog电影感

这次我们来看一个针对大疆 Pocket 4P 相机 D-LOG2 色彩模式的实测项目。核心不是讲复杂的色彩理论,而是直接告诉你:用 D-LOG2 拍出来的灰片,能不能通过几款定制 LUT(查找表)快速调出旅行 Vlog 所需的氛围感&#xff0c…

2026/8/21 1:12:08
FastAPI 实战指南:从声明式开发到生产部署

FastAPI 实战指南:从声明式开发到生产部署

如果你正在用 Flask 或 Django 写 API,感觉开发效率还行,但一遇到自动文档、数据验证、异步支持这些“现代”需求,就得四处找插件、写一堆胶水代码,那么这篇文章就是为你准备的。 FastAPI 最近在 Python 后端圈的热度&#xff0c…

2026/8/21 1:12:08
网络工程师实战能力构建:从零基础到解决实际问题的知识体系与学习方法

网络工程师实战能力构建:从零基础到解决实际问题的知识体系与学习方法

上周,一个刚转行做运维的朋友深夜发来消息,语气里满是困惑:“哥,我看了好多‘零基础速成网络工程师’的视频,每个都说几天就能精通,工具包也领了一堆。可真到公司让我配个VLAN、排查个环路,脑子…

2026/8/21 1:12:08
从视频到可仿真动态世界:动态重建的核心挑战与技术演进

从视频到可仿真动态世界:动态重建的核心挑战与技术演进

你有没有想过,有一天,你随手拍下的一段日常视频,比如孩子在公园里玩耍,或者一个快递机器人在仓库里穿梭,就能在电脑里瞬间生成一个可以“玩”起来的虚拟世界?在这个世界里,你可以暂停、倒放、从…

2026/8/21 1:12:08
AI 生成 PPT 实战手册:5 大工具横评 + 提示词工程 + 自动化方案

AI 生成 PPT 实战手册:5 大工具横评 + 提示词工程 + 自动化方案

AI 生成 PPT 实战手册:5 大工具横评 提示词工程 自动化方案 一份高质量 PPT 的传统制作周期是 1~3 小时:列大纲、找模板、配图、调字号、对齐……2023 年起,这一套流程被 AIGC 重写了。本文横评 5 款主流 AI 生成 PPT 工具&…

2026/8/21 1:12:08
个人微信API二次开发:朋友圈点赞新动态漏赞

个人微信API二次开发:朋友圈点赞新动态漏赞

私域 SOP:客户发新圈后 10 分钟内点赞。任务表里写死了上周的 snsId,今天全部赞在旧图上。客户以为被冷落。 点赞接口认动态 ID。发朋友圈那次的本地审核号不是 snsId。 字段和列表结构对照这里配:API 文档 每次先拉列表再赞第一条新的 G…

2026/8/21 1:07:06