首页/新闻资讯/正文详情

redux-form Selectors 官方指南:用 16 个状态选择器在应用任意位置读取表单状态

发布时间:2026/9/23 7:09:25 来源:云帆数科 栏目:资讯中心
redux-form Selectors 官方指南:用 16 个状态选择器在应用任意位置读取表单状态
redux-form Selectors 官方指南用 16 个状态选择器在应用任意位置读取表单状态【免费下载链接】redux-formA Higher Order Component using react-redux to keep form state in a Redux store项目地址: https://gitcode.com/gh_mirrors/re/redux-form本篇技术指南以 redux-form 官方文档 docs/api/Selectors.md 为骨架系统讲解 redux-form 提供的 16 个 Redux 状态选择器Selectors的签名、返回值、统一调用模式与底层实现。文中所有行为结论均可通过仓库源码 src/selectors 下的实现文件与 src/selectors/tests下的测试用例印证。读完本文你将能够在任何需要读取表单状态的组件、容器或工具函数中以一致的方式组合使用这些选择器并理解如何自定义表单 reducer 的挂载点与如何结合 ImmutableJS 使用。什么是 redux-form Selectors为什么需要它们redux-form 将每个表单的完整状态保存在 Redux store 中由redux-form的 reducer 统一管理。当你的应用需要在表单组件之外例如页头统计、全局校验提示、导航守卫、数据导出逻辑等读取某个表单的当前值、错误、元数据或提交状态时直接手写state.form.myForm.values这样的嵌套取值不仅容易出错而且会把内部状态结构泄漏到业务代码里。redux-form 提供了一套与官方 Redux 派生数据derived data理念一致的selectors用于在任何组件中查询任意表单的状态。它们统一从包入口 src/index.js 导出例如import { getFormValues, getFormInitialValues, getFormSyncErrors, getFormMeta, getFormAsyncErrors, getFormSyncWarnings, getFormSubmitErrors, getFormError, getFormNames, isDirty, isPristine, isValid, isInvalid, isSubmitting, hasSubmitSucceeded, hasSubmitFailed } from redux-form从源码结构看入口文件同时导出了isAsyncValidatingsrc/index.js对应实现位于 src/selectors/isAsyncValidating.js可用于判断表单是否正在进行异步校验用法与isSubmitting一致。统一的调用模式柯里化的 (formName)(state)官方文档强调除getFormNames外所有选择器都遵循完全相同的调用模式——先传入表单名称formName返回一个以 Redux 全局state为参数的函数const selectFormValues getFormValues(myForm) // 第一步传入表单名 const values selectFormValues(state) // 第二步传入全局 state因此它们天然可以与react-redux的connect无缝配合这也是官方文档给出的标准用法MyComponent connect(state ({ formValues: getFormValues(myForm)(state), initialValues: getFormInitialValues(myForm)(state), formSyncErrors: getFormSyncErrors(myForm)(state), fields: getFormMeta(myForm)(state), formAsyncErrors: getFormAsyncErrors(myForm)(state), syncWarnings: getFormSyncWarnings(myForm)(state), submitErrors: getFormSubmitErrors(myForm)(state), formError: getFormError(myForm)(state), names: getFormNames()(state), dirty: isDirty(myForm)(state), pristine: isPristine(myForm)(state), valid: isValid(myForm)(state), invalid: isInvalid(myForm)(state), submitting: isSubmitting(myForm)(state), submitSucceeded: hasSubmitSucceeded(myForm)(state), submitFailed: hasSubmitFailed(myForm)(state) }))(MyComponent)未文档化的最终参数getFormState所有选择器还接受一个未在文档中重点标注的最终参数getFormState()用于指定从根 Redux reducer 中取出redux-formreducer 挂载点的函数。其默认实现是state state.form即默认假设你已经将redux-form的 reducer 挂载在根 state 的form键下。如果你使用了自定义挂载点例如import { reducer as formReducer } from redux-form combineReducers({ app: appReducer, forms: formReducer }) // 使用自定义挂载点时 getFormValues(myForm, state state.forms)(state)从源码看这个默认值是在每个选择器内部以getFormState || (state getIn(state, form))的方式兜底实现的例如 src/selectors/getFormValues.js。注意这里使用结构层提供的getIn而不是原生的state.form这正是选择器能够同时兼容普通对象与 ImmutableJS 结构的关键。选择器读取的状态切片速查结合各选择器的源码实现可以精确汇总出每个选择器实际读取的 state 路径formState即getFormState(state)的结果选择器实际读取路径源码依据返回类型getFormValues${form}.valuesgetFormValues.jsObjectgetFormInitialValues${form}.initialgetFormInitialValues.jsObjectgetFormError${form}.errorgetFormError.jsanygetFormSyncErrors${form}.syncErrors缺失时返回emptygetFormSyncErrors.jsObjectgetFormMeta${form}.fields缺失时返回emptygetFormMeta.jsObjectgetFormAsyncErrors${form}.asyncErrorsgetFormAsyncErrors.jsObjectgetFormSyncWarnings${form}.syncWarnings缺失时返回emptygetFormSyncWarnings.jsObjectgetFormSubmitErrors${form}.submitErrors缺失时返回emptygetFormSubmitErrors.jsObjectgetFormNames直接对formState取keysgetFormNames.jsArray / Immutable ListisSubmitting${form}.submitting布尔化isSubmitting.jsbooleanhasSubmitSucceeded${form}.submitSucceeded布尔化hasSubmitSucceeded.jsbooleanhasSubmitFailed${form}.submitFailed布尔化hasSubmitFailed.jsbooleanisDirty、isPristine、isValid、isInvalid是组合型选择器内部逻辑更复杂将在下文单独展开。完整的状态结构说明可参考 docs/api/Reducer.md。逐个详解16 个选择器的签名与语义数据类选择器读取表单数据getFormValues(formName: String)→(state) formValues: Object实时获取表单当前的值即用户在表单中最新输入的内容。实现为直接读取${form}.valuesgetFormValues.js。这是最常用的选择器之一常与change、initialize等 action 配合观察表单变化。getFormInitialValues(formName: String)→(state) formInitialValues: Object获取表单的初始值通过initialValues属性或initializeaction 设置读取路径为${form}.initialgetFormInitialValues.js。该值与isPristine/isDirty的计算密切相关。错误与警告类选择器getFormError(formName: String)→(state) formError: any返回表单级错误——即通过特殊属性_error设置的表单整体错误例如提交失败时的服务器消息读取${form}.errorgetFormError.js。注意它与字段级错误存放在syncErrors等对象中、以字段名为 key不同。getFormSyncErrors(formName: String)→(state) formSyncErrors: Object返回表单的同步校验错误即通过validate函数在每次值变化时同步计算出的错误对象key 为字段名读取${form}.syncErrorsgetFormSyncErrors.js。没有错误时返回结构层定义的empty普通对象结构下为{}。getFormAsyncErrors(formName: String)→(state) formAsyncErrors: Object返回表单的异步校验错误即通过asyncValidate函数产生的错误读取${form}.asyncErrorsgetFormAsyncErrors.js。getFormSyncWarnings(formName: String)→(state) formSyncWarnings: Object返回表单的同步警告即通过warn函数产生的非阻塞性提示不阻止提交但会显示读取${form}.syncWarningsgetFormSyncWarnings.js。getFormSubmitErrors(formName: String)→(state) formSubmitErrors: Object返回表单的提交校验错误即handleSubmit抛出SubmissionError时写入的字段级错误读取${form}.submitErrorsgetFormSubmitErrors.js。关于SubmissionError的完整用法见 docs/api/SubmissionError.md。字段元数据类选择器getFormMeta(formName: String)→(state) formMeta: Object返回表单各字段的元数据主要包括touched是否被触碰过与visited是否被聚焦过读取${form}.fieldsgetFormMeta.js。官方文档特别提醒redux-form惰性创建formMeta对象即只有字段被 visited/touched 后才会出现对应条目。因此缺失的属性意味着该字段或字段组既未被访问也未被触碰在判断用户是否触碰过某字段时不能简单用hasOwnProperty之外的方式处理。getFormNames()→(state) formNames: Array获取 redux-form 当前管理的所有表单名称。这是唯一不需要传表单名的选择器其内部直接对getFormState(state)取keysgetFormNames.js。官方文档解释了它为何也采用返回函数的函数这一形式原因有二与其他选择器保持对称调用方式统一允许传入上文所述的getFormState参数从而支持自定义 reducer 挂载点。如果使用 ImmutableJS返回的是List而非原生数组详见后文 ImmutableJS 章节。布尔状态类选择器isDirty(formName: String)→(state, ...fields: String[]) dirty: boolean当表单的值相对于初始值initialValues发生过改变时返回true是isPristine的反义。从源码看isDirty是isPristine的简单取反isDirty.js 直接复用createIsPristine并返回!isPristine(state, ...fields)。isPristine(formName: String)→(state, ...fields: String[]) pristine: boolean当表单的值未曾偏离初始值时返回true。其实现isPristine.js展示了 redux-form 判断逻辑的两个关键点字段级筛选当传入fields参数时使用fields.every(...)逐一比较initial.field与values.field即只有指定字段全部 pristine才返回true整表判断未传字段时将整个initial与values通过结构层的deepEqual做深比较。isValid(formName: String)→(state) valid: boolean当表单没有同步、异步或提交错误时返回true是isInvalid的反义。这是逻辑最复杂的选择器其实现isValid.js依次检查表单级同步错误${form}.syncError表单级错误${form}.error即_error各级错误对象syncErrors、asyncErrors、submitErrors是否存在若存在错误对象则遍历registeredFields中注册次数大于 0 的字段用hasError实现见 src/hasError.js判断这些字段是否真正命中错误。值得注意的一个源码级细节createIsValid的工厂函数还接受一个未文档化的第三个参数ignoreSubmitErrors: ?boolean falseisValid.js置为true时会忽略提交错误对有效性判断的影响。isInvalid(formName: String)→(state) invalid: boolean当表单存在同步、异步或提交错误时返回true实现为isValid的简单取反isInvalid.js。isSubmitting(formName: String)→(state) submitting: boolean表单正在提交中时返回true即handleSubmit已触发且尚未结束读取${form}.submitting并布尔化isSubmitting.js。常用于提交按钮的 loading 态。hasSubmitSucceeded(formName: String)→(state) submitSucceeded: boolean表单此前曾成功提交过时返回true读取${form}.submitSucceededhasSubmitSucceeded.js。典型场景是提交成功后展示成功提示条。hasSubmitFailed(formName: String)→(state) submitFailed: boolean表单此前提交失败过时返回true读取${form}.submitFailedhasSubmitFailed.js。可用于失败后高亮错误区域。实战用 ...fields 参数做字段级 pristine/dirty 判断isDirty与isPristine是仅有的两个支持字段级筛选的选择器这也是它们的签名中...fields: String[]的含义。例如在仅当地址字段被修改过时提示保存的场景const mapStateToProps state ({ // 只要 address.city 或 address.zip 任一被改动addressDirty 即为 true addressDirty: isDirty(shippingForm, address.city, address.zip)(state) })从 isPristine.js 的实现可以看到字段级判断使用every只有所有指定字段都与初始值相等时才判定为 pristine因此任一字段被修改都会使isDirty变真。注意字段名支持嵌套路径写法如address.city这是因为读取时经由结构层的getIn进行路径解析。进阶自定义 getFormState 挂载点默认挂载点假设 reducer 挂在state.form。如果出于代码组织考虑使用了其他挂载键所有选择器包括getFormNames都接受getFormState作为额外参数。官方文档给出的一般形式是getFormValues(myForm, getFormState)(state)其中getFormState是接收根 state、返回表单状态树的函数。这在多 reducer、微前端拆分或测试中注入假状态时都很有用。例如在测试中模拟一个极小状态树const state { myForm: { values: { name: Ada } } } const values getFormValues(myForm, s s)(state) // 表单状态树就是整个 state // values { name: Ada }这一点在对应测试中也有体现例如 src/selectors/tests/getFormValues.spec.js 等测试文件。与 ImmutableJS 的配合如果项目使用 ImmutableJSredux-form 提供了对应的 immutable 版本仓库 src/immutable 目录下为每个选择器提供了基于 immutable 结构的实现如 src/immutable/getFormValues.js并通过包入口 immutable.js 导出。官方文档明确指出使用 ImmutableJS 时getFormNames()返回的是List而非原生数组。由于所有选择器内部统一通过结构层src/structure/plain 与 src/structure/immutable的getIn、keys、deepEqual、empty抽象访问状态同一套 API 在两种数据结构下行为一致。更多说明参见 docs/faq/ImmutableJs.md。与 formValueSelector / formValues 的关系需要区分的是本文的选择器是读取整张表单某个切面的通用工具而formValueSelectordocs/api/FormValueSelector.md实现见 src/formValueSelector.js与formValuesdocs/api/FormValues.md则是按字段名读取具体值的高阶封装。若只需要单个字段的当前值formValueSelector(state).get(state, fieldName)更直接若需要把多个字段值注入组件formValues组件 API 更声明式。二者与本文的选择器互补使用共同覆盖表单状态读取的各类场景。源码与测试导航选择器统一实现目录src/selectors每个选择器一个文件均为createXxx(structure)工厂函数形态类型声明目录内每文件对应的*.types.js.flow如 src/selectors/getFormValues.types.js.flow仓库级 Flow 类型定义见 src/types.js.flow单元测试src/selectors/tests下为每个选择器提供了独立的 spec如getFormValues.spec.js、isPristine.spec.js、isValid.spec.js等可作为理解边界行为的可执行示例包入口导出src/index.js普通结构与 src/immutableImmutableJS 结构状态结构整体说明docs/api/Reducer.md提交错误来源docs/api/SubmissionError.md。从源码结构可以推断这套选择器 API 的工厂 柯里化设计createXxx(structure) → (form, getFormState) → (state) value是为了同时服务于普通对象与 ImmutableJS 两种结构层structure参数在 src/selectors/index 相关入口 注入从而在不改变对外签名的情况下保持两套实现的代码完全同构。理解这一点后你既能放心地在业务代码中使用这套统一 API也能在需要时按同样的模式扩展自己的自定义选择器。【免费下载链接】redux-formA Higher Order Component using react-redux to keep form state in a Redux store项目地址: https://gitcode.com/gh_mirrors/re/redux-form创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

单招集训选校区重要吗?湘楚有才自有封闭校区对比普通集训场地优势详解
单招集训选校区重要吗?湘楚有才自有封闭校区对比普通集训场地优势详解

很多备战湖南单招的考生和家长,在选择集训机构时,过度关注课程价格、宣传噱头,却忽略了集训场地与校园环境对备考结果的决定性影响。事实上,单招备考是一场长期的耐力比拼,备考环境、管理模式、学习氛围,直接影响考生的复习状态、自律程度、提分效率,最终决定单招上岸结果。市面… · 2026/9/23 7:09:19

Mooncake KV 传输与缓存:vLLM 显存优化实战
Mooncake KV 传输与缓存:vLLM 显存优化实战

1. 从一次显存告急说起:Mooncake 到底在 vLLM 里干了什么第一次在生产环境里被 KV Cache 显存打爆,是在一个 7B 模型、并发 64 的压测场景下。GPU 利用率看着不高,但请求排队时间一路飙升,日志里全是 preemption 和 recompute 的痕… · 2026/9/23 7:09:07

标准化茶叶评鉴实训室建设与数字化管理实践
标准化茶叶评鉴实训室建设与数字化管理实践

1. 标准化茶叶评鉴实训室的建设背景与价值茶叶评鉴作为茶产业链中的核心技术环节,其标准化程度直接影响着茶叶品质评价的客观性与一致性。传统"师带徒"式的感官训练模式存在主观性强、标准不统一等问题,而现代茶叶产业对专业评鉴人才的需求正呈… · 2026/9/23 7:09:07

从‘cua‘的爆火看网络热词的传播密码与生命周期
从‘cua‘的爆火看网络热词的传播密码与生命周期

1. 全网都在刷"cua"?先搞懂它到底是个啥最近几天,我刷短视频和社交平台的时候,发现评论区突然被同一个词刷屏了——"cua"。一开始我以为是某个新出的软件缩写,或者是某个圈子的黑话,结果翻了一圈才… · 2026/9/23 7:54:01

Function Calling 工具调用的权限沙箱:基于 Docker 与 gVisor 的多租户代码执行环境
Function Calling 工具调用的权限沙箱:基于 Docker 与 gVisor 的多租户代码执行环境

Function Calling 工具调用的权限沙箱:基于 Docker 与 gVisor 的多租户代码执行环境在现代大模型智能体(Agent)赋能的高级分析场景(如 Code Interpreter、自动化报表生成、复杂数学建模)中,大模型生成的 动… · 2026/9/23 7:54:01

新能源复合能源系统Simulink建模与优化策略
新能源复合能源系统Simulink建模与优化策略

1. 项目背景与核心价值在新能源动力系统领域,如何实现多能源的高效协同一直是个经典难题。三年前我在参与某特种车辆项目时,就遇到过燃料电池瞬态响应慢导致加速性能不达标的情况。当时尝试在MATLAB/Simulink环境下搭建的复合能源管理系统,最… · 2026/9/23 7:54:01

腾讯云FDE认证全解析:岗位本质、备考路径与生态机会
腾讯云FDE认证全解析:岗位本质、备考路径与生态机会

腾讯云这次把FDE认证推到台前,确实让不少做云交付、解决方案的朋友眼前一亮。FDE这个岗位,说白了就是站在客户现场、把云方案真正落地的工程师,跟传统运维、后端开发有交集但又完全不是一回事。行业里一直缺一个能衡量这类能力的标准&#xf… · 2026/9/23 7:54:01

单片机选型三阶段:开发适配、应用验证与量产配套
单片机选型三阶段:开发适配、应用验证与量产配套

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/23 7:54:01

深入解析Linux信号处理:从sigaction到自定义框架实战
深入解析Linux信号处理:从sigaction到自定义框架实战

1. 从一次线上事故说起:为什么标准信号处理不够用三年前我负责维护一套高并发的日志采集服务,某天凌晨收到告警:采集进程僵死,日志堆积超过两千万条。登上去一看,进程状态是D(不可中断睡眠)&… · 2026/9/23 7:53:55

3招搞定手机怎么下载微信面试难题实战项目解析
3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧
Win7无线热点配置工具源码解析:解决API失效的3个实战技巧

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧 Win7无线热点配置工具在Win10/11上跑不动?不是你的问题,是版本升级后 API 全变了。很多老项目里的 netsh wlan… · 2026/9/23 0:00:36

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码