前端UI组件【免费下载链接】redux-formA Higher Order Component using react-redux to keep form state in a Redux store项目地址https://gitcode.com/gh_mirrors/re/redux-form点击查看免费下载reduxForm()装饰器HOC在包装你的表单组件时会注入一组丰富的props它们分为「状态类」与「操作类」两类前者如实反映 Redux Store 中表单的当前状态是否 dirty、是否 valid、是否在提交中……后者是一批已绑定到当前表单名的 action creatorchange、blur、reset、array.*……。本文以 Props.md 为骨架结合src/reduxForm.js、src/createReduxForm.js 与 src/actions.js 的源码实现逐一讲解这些 props 的含义、典型用法与底层原理帮助你准确判断「哪个 prop 该在何时使用、由谁驱动、副作用是什么」。说明本文讨论的 props 是redux-form生成并注入给被装饰组件的 props你在使用MyForm {...config}/时自行传入的 props如onSubmit、initialValues在 ReduxForm.md 中另有说明。一、用propTypes享受完整的类型检查如果希望为被装饰组件声明严格的PropTypes无需手写redux-form已从 src/propTypes.js 导出全部这些 props 的类型定义含isRequired标记直接展开使用即可import { reduxForm, propTypes } from redux-form class SimpleForm extends React.Component { static propTypes { ...propTypes // other props you might be using } // ... }在 src/propTypes.js 中可以看到formPropTypes的定义状态类 props如anyTouched、dirty、pristine、invalid、valid、submitting、submitFailed、submitSucceeded、initialized大多为bool.isRequiredarray被定义为shape({...})其中insert/move/pop/push/remove/removeAll/shift/splice/swap/unshift十个方法均为func.isRequirederror、warning、initialValues则为可选。值得注意formPropTypes中还包含文档未逐条展开但确实注入的内部 props如pure是否实现shouldComponentUpdate、submitAsSideEffectonSubmit返回值是否会被 dispatch、triggerSubmit与clearSubmit触发式提交机制以及未被透传到组件、仅用于内部连接的dispatch。这些成员正是「状态类 操作类」分类之外的第三类由redux-form内部消费的机制类 props。二、状态类 props表单当前“长什么样”以下 props 全部由connect()的mapStateToProps从 Redux Store 的 form 状态计算而来见 src/createReduxForm.js只读、不可直接修改。prop类型含义anyTouchedboolean只要有任一字段被标记为touched即为true全部未触碰则为false。由 store 中的anyTouched计算!!getIn(formState, anyTouched)dirtyboolean表单数据相对初始化值发生了变化与pristine互斥源码中直接dirty: !pristinepristineboolean表单数据与初始化值完全相同deepEqual(initial, values)为真时为trueinvalidboolean存在校验错误源码中为invalid: !validvalidboolean通过校验无错误由isValid(form, getFormState, false)选择器计算errorany整个表单的通用错误来自校验结果中的_error键同步校验validate、异步校验、或onSubmit的 rejected promiseSubmissionError中的_errorwarningany整个表单的通用警告来自同步警告函数warn结果中的_warning键formstring表单名即传给reduxForm()装饰器config.form或传入被装饰组件的formpropinitializedboolean表单是否已用初始值初始化过源码中initialized !!stateInitial即 store 中initial存在即视为已初始化initialValuesObject初始化表单数据所用的initialValues对象与传给reduxForm的相同submittingboolean表单是否正在提交。仅当onSubmit返回 promise 时有效promise 解析/拒绝前一直为truesubmitFailedboolean初始为false只要onSubmit因任何原因失败即置true下一次成功提交恢复falsestore 键submitFailedsubmitSucceededboolean初始为falseonSubmit成功后置true下一次失败提交恢复falsestore 键submitSucceededasyncValidatingString \| boolean异步校验状态false表示没有进行中true表示提交前的异步校验运行中字符串表示「该字段失焦触发了异步校验」的字段名两个易混淆的状态对需要特别区分dirty/pristine描述「数据是否偏离初始值」与用户是否触碰无关initialize()、reset()都会使其回到pristine。valid/invalid描述「当前是否有校验错误」由同步、异步、字段级校验共同决定validExceptSubmit这类内部计算isValid(form, getFormState, true)用于在提交时判断「除提交错误外是否有效」。asyncValidating的三态设计在 src/createReduxForm.js 中体现为getIn(formState, asyncValidating) || falseStore 中存的是触发字段名或true取不到则为false。UI 上可用它来显示 loading 状态并区分「整表校验中」与「某字段 blur 触发的校验中」。三、核心操作 props读写表单状态与提交表单handleSubmit(eventOrSubmit) : Function这是表单提交的入口函数应传给form onSubmit{handleSubmit}或button onClick{handleSubmit}。它执行完整的提交流程同步校验 异步校验若校验不通过则置submitFailed并返回错误对象不会调用onSubmit校验通过后调用this.props.onSubmit(data)data为表单数据若onSubmit返回 promise则submitting保持true直到 promise 解析/拒绝失败处理若 promise 被new SubmissionError({ field1: error, ... })这样的对象拒绝提交错误会被注入到各字段的errorprop与异步校验错误行为一致错误若挂在整个表单上可用_error作为字段名它将作为errorprop 暴露。handleSubmit有且仅有两种等价用法用法 1把函数传给它推荐用于按钮;button onClick{handleSubmit(data { // 此时校验已通过data 一定有效 })} Submit /button用法 2把函数作为onSubmitprop 传入被装饰组件;MyDecoratedForm onSubmit{data { // 此时校验已通过data 一定有效 }} /从源码看src/handleSubmit.jshandleSubmit的完整链路为touch(...fields)标记全部字段 → 若valid || persistentSubmitErrors则进入异步校验与executeSubmit否则直接setSubmitFailed并合并asyncErrors/syncErrors返回。executeSubmitsrc/handleSubmit.js中同步抛出SubmissionError会走stopSubmit(error) setSubmitFailedpromise 结果则按成功/失败分支调用stopSubmit/setSubmitSucceeded或stopSubmit/setSubmitFailed并提供onSubmitFail/onSubmitSuccess回调。SubmissionError的识别依赖 src/SubmissionError.js 中的私有标记redux-form/submission-error-flag。另外handleSubmit在 src/createReduxForm.js 中被实现为submit方法既能接受事件对象判定事件走正常提交且用submitPromise防止重复提交也能接受「提交函数本身」此时返回一个 deferred thunk等价于silenceEvents(() handleSubmit(...))。change(field, value)与change(formSectionName, value)修改 Redux Store 中某个字段的值或整体修改某个FormSection。这是一个绑定 action creator返回undefined。当value为函数时可获取当前字段值与整个表单值change(field, (fieldValue, allValues) { // 基于当前值计算新值 })源码层面注入的change是带默认参数的绑定函数src/createReduxForm.jsconst boundChange (field, value) change( initialProps.form, // 自动绑定表单名 field, value, !!initialProps.touchOnChange, // 是否顺带 touch !!initialProps.persistentSubmitErrors // 是否保留提交错误 )即change的副作用受reduxForm配置项touchOnChange默认false与persistentSubmitErrors默认false控制二者均可在 ReduxForm.md 中配置。blur(field, value)与autofill(field, value)blur(field, value)在 Redux Store 中把字段标记为失焦blurred注入版本同样携带touchOnBlur默认值true即 blur 时自动标记touchedautofill(field, value)设置字段值并标记为autofilled。适合「程序化填充但需让用户感知」的场景——字段的meta.autofilled会变为true从而可通过样式区分。autofilled标记存于 store 的字段元数据中fields[field].autofilledField组件的meta.autofilled直接读取该值相关类型定义见 src/propTypes.js测试覆盖见 src/tests/helpers/reducer.autofill.js。initialize(data)/initialized/initialValuesinitialize(data)把表单数据重置为给定值此后dirty/pristine均由「当前数据 vs 这组初始化值」比较得出。initialized表示是否已初始化initialValues即初始化对象本身。在 src/createReduxForm.js 的initIfNeeded中可以看到自动初始化逻辑组件挂载时若存在initialValues且尚未initialized或配置了enableReinitialize会自动调用initializekeepDirtyOnReinitialize与keepValues会以otherMeta的形式传入 actionsrc/actions.js。reset()与resetSection(...sections)reset()把表单所有值重置回初始化状态恢复pristineresetSection(...sections)只重置指定表单分区FormSection的值其余分区保留。对应 action creatorsrc/actions.js分别派发RESET与RESET_SECTION动作resetSection的 sections 列表进入meta.sections供 reducer 按路径局部重置docs/api/Reducer.md 有对应动作说明。destroy()销毁 Redux Store 中的表单状态。默认情况下componentWillUnmount()时redux-form会自动调用受destroyOnUnmount配置控制默认true见 src/createReduxForm.js。手动调用可用于提前清理表单数据。touch(...fields)与untouch(...fields)touch(...fields)把给定字段标记为touched从而触发错误显示很多表单「提交时统一显示错误」就是先touch全部字段untouch(...fields)清除字段的touched标记。handleSubmit的第一步就是touch(...fields)见前文源码链路这也是为什么提交后所有字段错误会一次性显示。clearAsyncError(field)与clearFields(...)clearAsyncError(field)清除某字段的异步校验错误clearFields(keepTouched, persistentSubmitErrors, ...fields)批量清空指定字段的值有initialValue的字段会重置回初始值。若keepTouched为true已touched字段的值会被保留若persistentSubmitErrors为true当前有提交错误的字段值会被保留。对应的 src/actions.js 中clearFields的 action 形如{ type: CLEAR_FIELDS, meta: { form, keepTouched, persistentSubmitErrors, fields } }四、array.*数组字段的十个预绑定操作array是一组已预绑定表单名的 action creator专用于操作表单中的数组字段与FieldArray配套。它们全部是绑定 action creator调用不返回任何值。在 src/createReduxForm.js 中这十个方法由bindActionCreators把「已绑定 form 名」的动作包装为可 dispatch 函数后聚合为array对象方法签名行为array.insert(field, index, value)向指定数组字段的index处插入值array.move(field, from, to)把from索引处的值移动到to索引array.pop(field)弹出数组字段末尾的值array.push(field, value)向数组字段末尾追加值array.remove(field, index)移除指定索引处的值array.removeAll(field)移除数组字段中的所有值array.shift(field)从数组开头移出一个值array.splice(field, index, removeNum, value)对数组执行Array.splice语义的操作array.swap(field, indexA, indexB)交换两个索引处的值array.unshift(field, value)向数组开头插入值典型用法例如动态增删「地址列表」// 向 hobbies 数组追加一项 this.props.array.push(hobbies, swimming) // 移除第 2 项 this.props.array.remove(hobbies, 1) // 交换第 0 项与第 2 项 this.props.array.swap(hobbies, 0, 2)源码细节src/actions.jsarray.swap会校验索引indexA indexB或负数都会直接抛错array.splice仅在value ! undefined时才携带payload从而精确模拟原生Array.splice的「只删不加」与「删加并用」两种形态。每个动作都以ARRAY_*常量作为type见 src/actionTypes.jsreducer 中对应的arrayInsert/arrayMove/...分支负责实际状态变更测试覆盖见 src/tests/helpers 下的reducer.array*.js系列。五、asyncValidate与asyncValidating异步校验联动asyncValidate : Function当异步校验开启配置了asyncValidate时可手动调用以触发一次异步校验asyncValidating : String | boolean上一节已述的三态状态值。注意注入给组件的asyncValidate是经过包装的方法src/createReduxForm.js它根据触发场景submit/blur/change与配置asyncBlurFields、asyncChangeFields判断是否需要校验并调用shouldAsyncValidate做最终决策提交场景下name为空则整表校验。校验期间派发startAsyncValidation完成后派发stopAsyncValidation错误对象含键时 action 的error标记为true见 src/actions.js。校验未通过时错误按字段写入asyncErrors最终通过mergeErrors与同步错误合并展示。六、props 注入机制与「propNamespace」重命名这些 props 是如何被注入的src/createReduxForm.js 的render()中reduxFormProps显式收集了对外暴露的成员array、anyTouched、asyncValidating、blur、change、destroy、dirty、error、form、handleSubmit、initialize、initialized、initialValues、invalid、pristine、reset、resetSection、submitting、submitFailed、submitSucceeded、touch、untouch、valid、warning等再与剩余普通 props 合并后渲染被包装组件const reduxFormProps { array, anyTouched, asyncValidate, asyncValidating, ... } const propsToPass { ...(propNamespace ? { [propNamespace]: reduxFormProps } : reduxFormProps), ...rest }这就是propNamespace配置的落点当你在reduxForm(config)中指定propNamespace: myFormPropsReduxForm.md上述全部注入 props 会收敛到this.props.myFormProps.*之下避免与其他 HOC 注入的 props 命名冲突。同时注意Form.propTypessrc/createReduxForm.js声明的是你在装饰器上传入的配置 propsform、initialValues、validate、warn、touchOnBlur等与注入给组件的formPropTypes方向正好相反——阅读时不要混淆这两套 prop 集合。另外装饰器最外层组件src/createReduxForm.js还暴露了实例级 APIsubmit()、reset()、valid、invalid、pristine、dirty、values、fieldList、wrappedInstance可通过 ref 访问适合在测试或命令式场景中读取表单快照。七、最佳实践小结展示与提交submitting配合handleSubmitpromise 型onSubmit实现按钮 loadingsubmitFailed/submitSucceeded用于提交结果反馈error/warning用于整表级提示。错误展示时机anyTouchedtouch()组合实现「提交时统一展示错误」touchOnBlur默认开启则失焦即展示。数组字段一律通过array.*十个方法操作不要直接改写valuesFieldArray内部还提供同名实例方法fields.push等见 src/propTypes.js二者底层共享同一批 action。状态判定判断「用户是否改过」用pristine/dirty判断「能否提交」用valid/invalid不要混用。命名空间冲突多 HOC 叠加时通过propNamespace将注入 props 收敛到独立命名空间避免覆盖。类型安全直接复用导出的propTypes等价于 src/propTypes.js 的formPropTypes保持组件声明与注入 props 同步。import React from react import { reduxForm, propTypes } from redux-form class SimpleForm extends React.Component { static propTypes { ...propTypes } submit values { // 校验已通过这里拿到的是有效数据 return Promise.resolve(values) // 返回 promise 以驱动 submitting } render() { const { handleSubmit, pristine, reset, submitting, anyTouched, error } this.props return ( form onSubmit{handleSubmit(this.submit)} {/* 字段组件略 */} {error div classNameerror{error}/div} div button typesubmit disabled{submitting}Submit/button button typebutton disabled{pristine || submitting} onClick{reset} Clear Values /button /div /form ) } } export default reduxForm({ form: simple })(SimpleForm)理解这套 props 体系就等于理解了redux-form的对外契约状态 props 告诉 UI「现在是什么」操作 props 驱动 Redux「变成什么」二者配合Field/FieldArray/FormSection等组件见 docs/api/README.md 的 API 总览即可在 React Redux 架构下构建可预测、可调试的复杂表单。赞分享前端UI组件【免费下载链接】redux-formA Higher Order Component using react-redux to keep form state in a Redux store项目地址https://gitcode.com/gh_mirrors/re/redux-form点击查看免费下载相关推荐react-jsonschema-form 表单 Props 完全指南掌握 Form / 的 40 API 参数与源码实现react jsonschema form 表单 Props 完全指南掌握 Form / 的 40 API 参数与源码实现 导读 Form / 是 re前端UI组件OptiScaler 实战手册按玩家场景配 DLSS 替代方案上采样与帧率提升一次搞懂OptiScaler 实战手册按玩家场景配 DLSS 替代方案上采样与帧率提升一次搞懂 装了 OptiScaler 之后我做得最多的动作就是在游戏里按 I图形学游戏开发redux-form 中 mapStateToProps 与 mapDispatchToProps 的组合使用如何优雅地叠加 connect 与 reduxForm 装饰器redux form 中 mapStateToProps 与 mapDispatchToProps 的组合使用如何优雅地叠加 connect 与 reduxF前端UI组件创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
工业串口服务器选型全攻略:核心技术解析与IPCSUN实测 上个月在一家汽车零部件厂配合做产线改造,客户的电表数据读到一半就断流。我蹲在配电柜旁边查了很久,最后发现问题和电表本身无关,而是那台串口服务器在变频器启动瞬间,RS-485收发芯片已经因为地电位差进入半损坏状态。换掉那台标… · 2026/9/23 2:58:38
Notepad3与VSCode正则查找替换对比:文本处理效率提升指南 说实话,我到现在都没想通一个事:VSCode 的功能比 Notepad3 不知道强到哪里去了,光插件生态就甩开一条街,但只要碰到那种“又臭又长、格式混乱、需要反复试错”的查找替换场景,我第一反应永远是打开 Notepad3࿰… · 2026/9/23 2:58:32
C++静态分析工具横向对比与工程化选型实战 1. 一次线上崩溃事故,把我推向了静态分析今年年初,一个运行了大半年的后台服务突然在生产环境出现偶发崩溃。崩溃信息极其隐蔽,只是某个线程在访问一个已经被释放的内存块时触发了段错误。我们团队花了整整三天,各种日志排查、GDB… · 2026/9/23 2:58:31
一个API Key打通所有大模型:2026年AI编程工具统一网关实战 2026年AI编程工具实战指南:如何用一个API Key打通所有主流大模型做AI编程这一年多,我手里攒下的API Key比银行卡还多。今天用DeepSeek写后端,明天换Claude调前端,后天项目组又让试GPT-5看Agent效果。每个AI编程工具都有一栏"… · 2026/9/23 3:42:20
图妹子实战避坑:3个常见报错,一文搞懂修复逻辑 图妹子实战避坑:3个常见报错,一文搞懂修复逻辑 官方文档翻了三遍还是报错?别急,图妹子这种工具链,坑往往不在逻辑,而在环境配置和依赖版本。我踩了两年坑,今天把最常见的三个报错场景拆解清楚,让你少走弯路。 坑一:依赖版本冲突导致启动崩溃… · 2026/9/23 3:42:20
蓝牙耳机前十品牌怎么选?降噪与续航双硬核指标深度解读 这几年被身边朋友和后台私信问得最多的一句话,就是“蓝牙耳机前十的品牌有哪些”。顺着这个问题往下聊,大家真正想知道的其实是另一件事:市面上到底哪几款耳机降噪和续航都足够能打,买回来不容易踩坑。“前十”作为一个榜单概念&a… · 2026/9/23 3:42:20
SWIR短波红外成像实现非接触式液位检测原理与实战 1. 项目概述:为什么用SWIR051AU拍不透明容器里的液体,比肉眼和可见光相机更靠谱?短波红外(SWIR)成像不是新概念,但真正把它用在工业现场“看穿”不透明容器液位这件事上,很多人还停留在“听说很… · 2026/9/23 3:42:20
Octop 1.0实测:一条命令自托管多智能体系统 我在一台腾讯云服务器上同时维护着对话、代码评审、知识库问答三个AI服务,最头疼的是三套系统各自独立,端口、配置文件、模型调用方式全都不一样,每次上线新功能都要改三处。Octop 1.0发布后,我第一时间在轻量应用服务器上做了部署… · 2026/9/23 3:42:20
YOLOv8血细胞检测实战:数据集划分与训练避坑指南 简介:面向血细胞自动检测任务的YOLO目标检测数据集,包含1000张真实场景医学显微图像,标注对象覆盖红细胞、白细胞与血小板,适用于医学影像分析及相关课程项目。资源包以VOC格式xml、COCO格式json和YOLO格式txt三种标签同步存放&am… · 2026/9/23 3:42:14
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29