前端【免费下载链接】rematchThe Redux Framework项目地址https://gitcode.com/gh_mirrors/re/rematch点击查看免费下载本文以 Rematch 仓库根目录 README 为主线系统讲解这个 The Redux Framework 的定位与核心能力如何在几行代码内定义 state、reducers 与 async effects 并生成一个可直接接入 React 的 Redux store。读完本文你将掌握 Rematch 的 Model 编写范式、init建店的完整流程、dispatch[model]action的底层生成机制、动态添加模型与多 Store 能力以及其插件体系与从原生 Redux 迁移的路径并能对照仓库源码packages/core验证每一处行为。什么是 Rematch特性清单Rematch 的官方定位是Redux best practices without the boilerplate——把 Redux 的最佳实践封装起来去掉 action types、action creators、switch 语句和 thunks核心包体积不到 1.4 kB见 README仓库根 package.json 中的 size-limit 配置对rematch/core设置了 2 kB 的体积上限且统计时忽略 redux 依赖可以印证这一约束。README 列出的完整特性如下无需任何配置No configuration needed大幅减少 Redux 样板代码Reduces Redux boilerplate内置副作用side-effects支持支持 React Devtools支持 TypeScript支持动态添加 reducers支持热更新hot-reloading允许创建多个 store支持 React Native可通过插件扩展并内置多个官方插件基于 redux-persist 的数据持久化rematch/persist用 immer.js 包装 state 的不可变更新rematch/immer基于 reselect 的选择器rematch/select等等loading、updated、typed-state 等见 docs/plugins/index.md从仓库结构看这是一个 Lerna Yarn workspaces 管理的 monorepo见 lerna.json 与 package.jsonpackages/目录下每个包对应一个核心或插件core、immer、loading、persist、select、typed-state、updated。快速上手一个模型搞定异步请求与全局状态README 用一段players模型演示了 Rematch 的核心理念几行代码即可实现对外部 API 的异步调用并把数据存进全局状态。完整继承自 README 的示例如下type PlayersState { players: PlayerModel[] } export const players createModelRootModel()({ state: { players: [], } as PlayersState, reducers: { SET_PLAYERS: (state: PlayersState, players: PlayerModel[]) { return { ...state, players, } }, }, effects: (dispatch) { const { players } dispatch return { async getPlayers(): Promiseany { let response await fetch(https://www.balldontlie.io/api/v1/players) let { data }: { data: PlayerModel[] } await response.json() players.SET_PLAYERS(data) }, } }, })这段代码里只有三样东西state初始状态、reducers同步纯函数修改、effects可 async/await 的副作用函数。没有 action type 常量、没有 switch、没有 thunk这正是 README 标题所强调的卖点。仓库中有一个与它同构的可运行实例examples/count-react-ts/src/models/dolphins.ts用createModelRootModel()定义了state: 0、incrementreducer 和带 500ms 延迟的incrementAsynceffect可作为最小参照。标准四步流程对应官方安装文档结合 docs/installation.md完整落地路径是四步Step 1定义模型。Model 把 state、reducers、async actions 收敛在一处描述 store 的一个切片。TypeScript 版用辅助函数createModel创建模型见 packages/core/src/index.ts#L18import { createModel } from rematch/core; import { RootModel } from .; export const count createModelRootModel()({ state: 0, // initial state reducers: { // 用纯函数处理状态变更 increment(state, payload: number) { return state payload; }, }, effects: (dispatch) ({ // 用不纯函数处理状态变更async/await 处理异步 async incrementAsync(payload: number, state) { console.log(This is current root state, state); await new Promise((resolve) setTimeout(resolve, 1000)); dispatch.count.increment(payload); }, }), });模型需要在./models/index.ts中汇总并导出RootModel接口import { Models } from rematch/core; import { count } from ./count; export interface RootModel extends ModelsRootModel { count: typeof count; } export const models: RootModel { count };官方文档特别提示state 会自动推断当 state 是复杂类型时用as断言即可参考 docs/installation.md 中 Example with a more complex state 一段与 examples/count-react-ts/src/models/questions.ts。Step 2init建店。init是你唯一需要调用的方法它构建一个完整配置好的 Redux storeimport { init, RematchDispatch, RematchRootState } from rematch/core; import { models, RootModel } from ./models; export const store init({ models, }); export type Store typeof store; export type Dispatch RematchDispatchRootModel; export type RootState RematchRootStateRootModel;Step 3dispatch 触发动作。dispatch 标准化了 action无需手写 action types 和 action creators支持两种等价写法const { dispatch } store; // state { count: 0 } // reducers dispatch({ type: count/increment, payload: 1 }); // state { count: 1 } dispatch.count.increment(1); // state { count: 2 } // effects dispatch({ type: count/incrementAsync, payload: 1 }); // 延迟后 state { count: 3 } dispatch.count.incrementAsync(1); // 延迟后 state { count: 4 }Step 4视图层。Rematch 与 react-redux 原生兼容connect、Provider均直接可用examples/count-react/src/App.js、examples/hooks-react-ts等目录都有可直接参考的完整接法。Redux vs Rematch官方对比表README 给出了如下对照可作为选型与迁移时的判断依据ReduxRematchsimple setup✔less boilerplate✔readability✔configurable✔✔redux devtools✔✔generated action creators✔asyncthunksasync/await关键点在最后两行Rematch 自动生成 action creators异步能力由内置 async/await 替代 redux-thunk同时保留 configurable 与 devtools 两项 Redux 原生优势后文的redux配置项和composeEnhancersWithDevtools实现会印证这一点。源码剖析init 之后发生了什么init的全部实现只有两行见 packages/core/src/index.ts#L8-L16export const init TModels, TExtraModels(initConfig?: InitConfig): RematchStore { const config createConfig(initConfig || {}) return createRematchStore(config) }1. createConfig补全默认值并让插件修改配置packages/core/src/config.ts#L11-L85 负责生成完整配置未提供name时自动命名为Rematch Store 0、Rematch Store 1……模块级计数器这也是多 Store 场景下 Devtools 中区分各 store 的依据models默认为{}plugins默认为[]redux段合并用户的 reducers、rootReducers、enhancers、middlewares、initialState并默认把devtoolOptions.name设为 store 名随后遍历config.plugins每个插件若声明了config可注入新模型、覆盖 initialState/reducers/enhancers/middlewares浅合并时原配置优先见文件尾部merge函数 config.ts#L91-L96。这就是插件可以在不改 Rematch 本身的情况下修改 setup的落点之一。2. createRematchStore装配 Redux store 的主流程packages/core/src/rematchStore.ts#L23-L70 是建店核心按顺序做六件事创建 bag存放 redux 配置、effects 注册表等内部值见 packages/core/src/bag.ts向 middlewares 数组推入createEffectsMiddlewareeffects 的执行引擎调用所有插件的createMiddleware钩子把插件 middleware 追加进来调 reduxStore.ts 的createReduxStore真正创建 Redux store对每个 model 分两遍处理prepareModel注入 dispatch 占位、生成 reducers dispatcher→enhanceModel生成 effects dispatcher、通知插件onModel钩子。源码注释明确说明分两步是为了让循环引用的模型也能在 effects 中用解构拿到彼此调用插件的onStoreCreated钩子并返回最终 store。其中addModel方法rematchStore.ts#L43-L50对应 README 宣称的支持动态添加 reducersaddModel(model: NamedModelTModels) { validateModel(model) createModelReducer(bag, model) prepareModel(rematchStore, model) enhanceModel(rematchStore, bag, model) reduxStore.replaceReducer(createRootReducer(bag)) reduxStore.dispatch({ type: redux/REPLACE }) }即新建模型 reducer → 生成 dispatchers →replaceReducer重建 root reducer 并触发一次空 action 刷新状态。3. 模型 reducer 与 action 命名约定packages/core/src/reduxStore.ts#L58-L106 的createModelReducer解释了count/increment这种 action 名的来源每个 reducer key 组合成modelName/reducerKey作为 action type若 key 本身已含/视为跨模型监听原样使用见isAlreadyActionNamereduxStore.ts#L181-L183生成的 combined reducer 只在该 action 命中时执行modelReducersaction.type否则返回原 state若模型定义了baseReducer会先经过 baseReducer 再进入 combined reducer最后经插件的onReducer钩子层层包装immer 插件正是借此把 reducer 包进produce。createRootReducerreduxStore.ts#L114-L143则把各模型 reducer 用combineReducers或用户自定义版本合并支持rootReducers在合并前对整体 state 做前置处理最后再经插件onRootReducer钩子包装persist 插件即在此介入。Redux store 的创建reduxStore.ts#L18-L44还支持用户自定义createStoreRedux 4 可传 store creator、devtoolComposer当检测不到window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__时自动回退Redux.composecomposeEnhancersWithDevtoolsreduxStore.ts#L167-L175——这解释了 README 特性表中 redux devtools ✔ 一栏在浏览器/Node 双环境下都成立的原因。4. dispatch[model][action] 的生成机制README 说 Rematch 提供 generated action creators其实现全在 packages/core/src/dispatcher.tscreateActionDispatcherdispatcher.ts#L19-L46为每个 action 生成一个可调用函数返回的 action 形如{ type: modelName/actionName, payload?, meta? }并调用rematch.dispatch(action)同时用Object.assign挂上isEffect标记区分 reducer 与 effect 的 dispatcher。createReducerDispatcher把 model 的每个 reducer 名映射成dispatch[model.name][reducerName]createEffectDispatcher把 model 的每个 effect 名映射成dispatch[model.name][effectName]并把 effect 函数以modelDispatcher为 this 绑定后注册进bag.effects。5. 内置 side-effects一个极简 middlewareREADME 特性 Built-in side-effects support 对应createEffectsMiddlewarerematchStore.ts#L72-L93逻辑非常直接if (action.type in bag.effects) { // 先执行对应的 reducer action如果存在 next(action) // 再执行 effect 并返回其结果 return (bag.effects as any)action.type, action.meta) } return next(action)也就是说 effect 不是独立的中间层库而是当 action type 命中bag.effects注册表时先跑 reducer 流水线、再执行同名 effect 函数的一个普通 Redux middleware。这解释了为什么effects: (dispatch) ({ async ... })里可以直接await——它就是一个被该 middleware 调用的原生 async 函数无需 redux-thunk对比表中 async: thunks → async/await 的由来。effects 测试用例见 packages/core/test/effects.test.ts行为验证可参考 packages/core/test/store.test.ts。多 Store同一个 init多个独立实例README 特性 Allows to create multiple stores 在 examples/multi-react/src/LeftStore.js 中有直接示范import { init } from rematch/core const count { state: 0, reducers: { increment(state) { return state 1 }, }, } export const store init({ name: left, models: { count, }, })同一目录下的RightStore.js再建一个 store 供页面右半部分使用。结合createConfig中自动递增的 store 命名多实例在 Devtools 中会以各自name区分。可组合的插件体系README 指出Rematch and its internals are all built upon a plugin pipeline。从源码看插件钩子至少包括config改配置、加模型、createMiddleware加 middleware、onStoreCreated改写 store 实例、onModel、onReducer包装模型 reducer、onRootReducer包装根 reducer——分别出现在 config.ts、rematchStore.ts#L34-L67 与 reduxStore.ts#L101-L140 中。此外插件还能通过exposed把属性暴露到 store 实例上rematchStore.ts#L132-L157 的addExposed会把插件暴露的函数包装成自动以 store 为首参的方法挂到 store 上例如store.select。官方插件全家桶见 docs/plugins/index.md 与packages/目录Immer 插件packages/immer/src/index.ts用 immer 包装 reducers可安全地可变式修改得到不可变 stateSelect 插件packages/select/src/index.ts为模型提供 reselect 风格的 selectorsPersist 插件packages/persist/src/index.tsredux-persist 的 Rematch 封装Loading 插件packages/loading/src/index.ts为 effects 自动维护 loading 指示状态Updated 插件packages/updated/src/index.ts记录模型/effects/reducers 上次触发时间。各插件均有独立测试如 packages/immer/test/immer.test.ts且根 package.json 的 size-limit 对每个插件包单独设了体积上限persist ≤ 200 B、select ≤ 500 B、updated ≤ 500 B 等插件本身极轻量。完整插件 API 见 docs/api-reference/plugins.md。从 Redux 迁移到 RematchREADME 的 Migrate From Redux 一节指出迁移可能只需对状态管理做小改动视图逻辑基本无需变动。对应文档 docs/migrating/from-redux.md 给出三步1. 先让 init 与现有 Redux 并存。init的redux段可以直接挂载原生 reducer 和 middlewareimport { init } from rematch/core; const store init({ redux: { reducers: { sharks }, middlewares: [thunk], }, });2. 把 reducer 逐个改写成 Model。原 Redux 的 action 常量 action creator switch 写法const INCREMENT sharks/increment; export const incrementSharks (payload: number) ({ type: INCREMENT, payload, }); export default (state 0, action: { payload: number; type: string }) { switch (action.type) { case INCREMENT: return state action.payload; default: return state; } };等价于一个 Rematch 模型源码层面createModelReducer会把increment注册为sharks/increment行为一致export default { state: 0, reducers: { increment: (state, payload: number) state payload, }, };3. 换成models并移除 thunkconst store init({ models: { sharks }, });由于 Rematch 底层仍是标准 Redux store 且兼容 react-redux视图层通常开箱即用。另见 v1 → v2 迁移指南 docs/migrating/from-v1-to-v2.md。工程结构速览如何在仓库中继续深入核心实现packages/core/src/index.tsinit/createModel导出、packages/core/src/rematchStore.ts建店主流程与 effects middleware、packages/core/src/dispatcher.tsdispatcher 生成、packages/core/src/reduxStore.tsreducer 合并与 store 创建、packages/core/src/config.ts配置装配测试packages/core/test/ 覆盖 config、dispatcher、effects、init、listener、multiple多 store、plugins、validate 等场景TypeScript 类型测试见 packages/core/test/ts_typings/可运行示例examples/ 下有 countJS/TS、hooks、multi多 store、persist、select、updated、loading、nextjs-blog、gatsby-example、all-plugins-react-ts 等十余个场景根 package.json 的 workspaces 已纳入其中四个 TS 示例完整 API 文档docs/api-reference/store.mdinit 配置参数、docs/api-reference/models.md模型结构、docs/api-reference/dispatcher.md 等贡献与规范CONTRIBUTING.md项目遵循 LICENSE 的 MIT 许可。小结Rematch 的核心主张可以浓缩为一句话把 Redux 的最佳实践约定编译进了框架本身——模型即切片modelName/actionName即 action 约定effects middleware 即 async/await 能力插件钩子即扩展点。它没有发明新的状态管理范式而是把combineReducers、middleware 与 action creator 生成这些 Redux 官方机制以最少样板的方式拼装好packages/core全部源码不足千行。对现有 Redux 项目而言迁移成本低视图层不动、reducer 逐模型改写对新建项目而言init({ models })一行即可获得完整 store再按需求叠加 immer/persist/select 等轻量插件即可。赞分享前端【免费下载链接】rematchThe Redux Framework项目地址https://gitcode.com/gh_mirrors/re/rematch点击查看免费下载相关推荐Vortex模组管理器终极指南从零开始掌握250游戏模组管理Vortex模组管理器终极指南从零开始掌握250游戏模组管理 你是否曾经因为模组冲突导致游戏崩溃而沮丧是否在不同游戏间切换模组时感到混乱不堪Vortex桌面应用Firefox for iOS 的 Redux State Reducer 初始化器清理用 Swift Copy Macro 消除样板代码Firefox for iOS 的 Redux State Reducer 初始化器清理用 Swift Copy Macro 消除样板代码 本篇文章以 Fir移动开发前端Redux DevTools 浏览器扩展架构剖析从注入脚本到 DevTools 面板的完整消息链路Redux DevTools 浏览器扩展架构剖析从注入脚本到 DevTools 面板的完整消息链路 Redux DevTools 浏览器扩展由多个相互隔离的执开发工具前端上一篇Mac Mouse Fix终极指南让普通鼠标在macOS上焕发新生下一篇pymobiledevice3社区贡献指南如何参与开源项目开发创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
Atlas 300V 24G跑YOLO目标检测:从模型转换到推理优化全攻略 上个月朋友给我扔过来一个问题:“Atlas 300V 24G是不是运算加速卡?我想拿它跑YOLOv8目标检测,预算就那么多,能不能干?”我一看,这问题其实把很多人绕进去的坑全踩了——名字里带“运算”,但它真… · 2026/9/25 5:36:46
Atlas 300V 24G部署YOLO推理全流程:选型、环境搭建与调优实践 前阵子刚拿到一台带Atlas 300V 24G推理卡的服务器,折腾了近一周,把YOLOv5s和YOLOv8s的推理链路完整跑通。这卡最近在技术群和私信里被问的频率很高,问题基本集中在两个:“atlas部署yolo到底怎么搞”和“atlas 300v 24g 是运算加速… · 2026/9/25 5:36:39
Atlas 300V 24G部署YOLOv5全流程实操与性能调优 先说结论:Atlas 300V 24G不是传统意义上的独立显卡,而是一张专为AI推理设计的运算加速卡。最近圈子里问得最多的就是它能不能跑YOLO、怎么部署、效果如何。这篇文章把我从零开始部署YOLOv5的完整过程、踩过的坑和性能调优经验全部写出来,给准… · 2026/9/25 6:01:28
C++ ADODB 实战:从 regtlibv12 注册到连接池调优 简介:这份资源面向在 C 环境下进行数据库开发的程序员与学习者,聚焦微软 ADODB(ActiveX Data Objects for Database)这一 COM 接口的实战应用。包内以 ADODatabase.h、ADORecordset.h 等头文件与对应 cpp 源码为核心,演… · 2026/9/25 6:01:28
创维E900V21E刷机全攻略:从硬件识别到救砖优化 这段时间前后处理了好几台创维E900V21E的刷机需求,这台移动定制盒子在二手市场流通量非常大,配置尚可但系统限制极多——预装全家桶、桌面广告、第三方应用装不进去,还时不时被运营商远程管控。很多人拿到手第一反应就是刷机,结果… · 2026/9/25 6:01:28
Harbor v2.5.5 ARM64离线部署实战:从安装包到避坑指南 简介:Harbor v2.5.5 离线安装包 ARM64 专版,面向需要在 ARM 架构服务器或内网环境中部署容器镜像仓库的运维与 DevOps 工程师,用于解决无公网环境下安装介质获取困难的问题。包体共 24 个文件,包含 docker-compose.yml、harbor.ym… · 2026/9/25 6:01:28
craft.js NodeTree 详解:以节点树结构表示 React 元素层级 前端 【免费下载链接】craft.js 🚀 A React Framework for building extensible drag and drop page editors 项目地址: https://gitcode.com/gh_mirrors/cr/craft.js 点击查看 免费下载 NodeTree 是 craft.js 中用于表示一棵 React 元素树(… · 2026/9/25 6:01:28
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37