当前位置: 首页 > news >正文

useEffect 通过 form.getFieldValue(‘xxx‘) 监听 Form表单变化

场景

子组件中,某一个表格的数据需要依赖于上级组件的某一个表单元素值进行计算。

毫无疑问,首先想到的肯定是监听 form 表单中元素的值,使用 useEffect 监听表单的变化,当值发生变化时,重新计算渲染。

首先说下我的代码结构:

Form 表单是一个子组件,表格组件也是一个子组件,且是比较深的子组件(包含在tab标签页下)。如果说 Form子组件是一级子组件,那么表格组件就是一个四级子组件。

在这种多层嵌套下,如何把 form 数据传递给对应的表格子组件?

毫无疑问,选择使用:useContext

在顶层组件中通过 Form.useForm() 定义 Form 实例,管理数据状态,通过 <context.Provider value={}></context.Provider>传递,表单子组件和表格子组件都可进行接收。

不过在子组件监听代码写好后,却发现了一个比较尴尬的问题:表单元素的值发生了改变,但子组件的useEffect 却没能监听到。

// 子组件
import React, { useContext } from 'react'
import context from 'xxx/xxx'const { form } = useContext<any>(context)useEffect(() => {console.log('监听到了变化')// 下面是具体的逻辑
}, [form.getFiledValue('xx')])

注意:

当时令我困惑的是:当 Form 表单组件的某个表单元素值改变时,虽然子组件 useEffect 没有监听到变化,但通过表格子组件的输入框的 onBlur 事件,调用 form.getFiledValue('xx'),却可以拿到最新的值。

分析

需求终归还是要往下开发的,监听不了,那就想办法监听!

在项目中,我是使用了 const [form] = Form.useForm(); 来创建 Form 实例,管理表单数据状态,这也是函数式组件推荐的一种方式。

通过使用 useForm ,会让表单成为 非受控组件,不用通过 useState 创建state 来维护数据。

而且 ant 官网 里面也说了:使用这种方式与其他获取数据的方式的区别:

Form 仅会对变更的 Field 进行刷新,从而避免完整的组件刷新可能引发的性能问题,因而无法在 render 阶段通过 form.getFieldsValue 来实时获取字段值。



看到这里,其实已经很清楚了,因为 使用了 useForm,导致表单变成了 非受控组件,不能通过 useState 来创建 state 维护数据,只能通过 form.getFieldsValue() / form.setFieldsValue() 来获取及设置表单数据,ant design 官方文档也有介绍。所以在这种情况下, 使用 useEffect 监听不到 form 表单的变化。



换句话说:form.getFieldValue('xxx'); 并不是响应式的,由其取到的值,并不会触发 UI 更新,即:它不是一个 state。

不过,可能有人会问:我之前也使用过 useEffect 来监听 form.getFieldValue(‘xxx’),UI也能正常渲染啊,你这里是不是说错了?

答: 没有说错,我自己之前也有这样的疑问,也遇到过这类问题。



在实际项目中,一个 react 组件的 re-render 次数是不可控的, 特别是代码写的不那么规范的时候,所以,当看到 UI 更新的时候,或许是在新的 re-render 中被连带着更新了;又或许是项目代码中 Form组件既使用了 form = {form} 属性,又使用了 initialValues 属性。如下所示:

//
const [form] = Form.useForm();<Form initialValues={formData} form={form} ref={formRef}> </Form>

解决方案

方案1

ant design @4.20 版本推出了一个新特性:Form.useWatch,可以直接获取 form 中字段对应的值,应该是可以监听到的,具体用法可以参考官网,这里不多做赘述。

可是 4.2 版本后才支持,我的项目版本是 4.12.3,暂不支持这个hooks,部门领导也不让进行 ant 升级,所以就没有尝试这种写法。

而且使用这种方法,固然可以监听到,不过性能不是太好,不建议使用。因为它会触发整个组件的 re-render,当组件比较大且监听 input 实时输入时,性能消耗就很恐怖。

方案2

拒绝使用 Form.useForm(),使用 initialValues 属性,是表单变成一个可控组件,拥有 state,就可以正常监听。

不过对于我的项目代码来说,改动量太大,不划算。

方案3

使用 useState 额外定义个 state ,当表单元素值发生变化时,使用 setState(),然后将其值通过 context.Provider传递,在子组件监听。

方案4

使用 useReducer

useReduceruseState 都是用来存储和更新 state,相当于 useState 的升级版。

type 数量较多时,建议使用 useReducer

方案5

Ant Plus 5 的 Watch 组件

专门用于监听表单字段变化,并更新局部UI。(没尝试过)

总结

其实核心要点就一句话:Form 内置方法,不是响应式的(即不是一个state),由其设置或者获取的值,不会触发UI更新,只能对变更的field进行刷新。想要对其进行监听也很简单,将其变成一个state即可。

相关文章:

useEffect 通过 form.getFieldValue(‘xxx‘) 监听 Form表单变化

场景 子组件中&#xff0c;某一个表格的数据需要依赖于上级组件的某一个表单元素值进行计算。 毫无疑问&#xff0c;首先想到的肯定是监听 form 表单中元素的值&#xff0c;使用 useEffect 监听表单的变化&#xff0c;当值发生变化时&#xff0c;重新计算渲染。 首先说下我的…...

【晓龙oba出品 - 黑科技解题系列】- 最小操作次数使数组元素相等

思路 算法归根到底就是找规律的游戏&#xff0c;我们首先来看一个现象&#xff1a; 以数组nums [1,2,3,4,5]为例 当我们将数组排序后&#xff0c;可以知道最小值为1,最大值为5&#xff0c;此时我们需要四次运算可以使最小值与最大值相等&#xff1a; 第一次&#xff1a;2,3,4,…...

Activity的启动和结束

onCreate&#xff1a;创建活动。此时会把页面布局加载进内存&#xff0c;进入了初始状态。onStart&#xff1a;开启活动。此时会把活动页面显示在屏幕上&#xff0c;进入了就绪状态。onResume&#xff1a;恢复活动。此时活动页面进入活跃状态&#xff0c;能够与用户正常交互&am…...

利用业务逻辑+OB分布式特性优化SQL

最近某人社局核心数据库上了OB&#xff0c;经常出现性能问题 某人社与我司合作多年&#xff0c;非常信任我司在数据库的专业能力&#xff0c;邀请我司过去看看能否提供帮助 与OB驻场工程师合作&#xff0c;抓取了一天的TOP SQL&#xff0c;跑得慢的SQL有几十条(注意只是某一天的…...

哈希表

文章目录什么是哈希问题引入哈希函数直接定址法除留余数法 &#xff08;常用、重点&#xff09;哈希冲突哈希冲突的解决方法闭散列开散列unordered_map && unordered_set 封装实现哈希的应用位图布隆过滤器哈希经典面试题哈希切分位图应用布隆过滤器什么是哈希 在上一…...

基于Halcon的MLP(多层感知神经网络)分类器分类操作实例

一、介绍 人工神经网络(Artificial Neural Network,ANN)简称神经网络(Neural Network,NN)或类神经网络,是一种模仿生物神经网络的结构和功能的数学模型或计算模型,用于对函数进行估计或近似。 MLP神经网络是一种基于神经网络、动态的分类器。MLP分类器使用神经…...

VR全景博物馆,打造7*24小时的线上参访体验

导语&#xff1a;博物馆作为人们了解历史、文化和艺术的重要场所&#xff0c;现在可以通过VR全景技术来进行展览&#xff0c;让参观者身临其境地感受历史文化的魅力。本文将介绍博物馆VR全景的特点、优势&#xff0c;以及如何使用VR全景技术来丰富博物馆的展览和教育活动。什么…...

Go 数据类型

基础数据类型 类型长度&#xff08;字节&#xff09;默认值说明bool1falsebyte10uint8&#xff0c;取值范围[0,255]rune40Unicode Code Point&#xff0c;int32int,uint4或者8032位或64位操作系统int8,uint810-128~127&#xff0c;0-255int16,uint1620-32768~32767&#xff0c…...

Mybatis-Plus学透?一篇足够(持续更新中)

01、Mybatis-Plus入门 一、简介 MyBatis-Plus&#xff08;简称 MP&#xff09;是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。如果你想对自己的项目进行技术升级&#xff0c;不妨尝试将mybatis换成Mybati…...

船用燃料油市场调研报告-主要企业、市场规模、份额及发展趋势

船用燃料油市场报告主要研究&#xff1a;市场规模&#xff1a; 产能、产量、销售、产值、价格、成本、利润等行业分析&#xff1a;原材料、市场应用、产品种类、市场需求、市场供给&#xff0c;下游市场分析、供应链分析等竞争分析&#xff1a;主要企业情况、市场份额、并购、扩…...

python趣味编程-奥赛罗游戏

在上一期我们用Python实现了一个高速公路汽车游戏的游戏&#xff0c;这一期我们继续使用Python实现一个简单的奥赛罗游戏&#xff0c;让我们开始今天的旅程吧~ 在Python中使用Turtle实现的奥赛罗游戏 在Python中使用Turtle的简单奥赛罗游戏 是一个以 Python 为程序设计语言的项…...

经典卷积模型回顾13—ResNetXt实现图像分类(matlab)

ResNetXt是ResNet的变种&#xff0c;在ResNet基础上引入了"split-transform-merge"的思想&#xff0c;旨在进一步提升模型的性能和准确率。ResNetXt模型的核心思想是通过对输入进行分组&#xff0c;然后对每个分组进行不同的变换&#xff0c;最后再将变换后的结果合并…...

Spring学习——Maven进阶

分模块开发与设计 创建模块 书写模块代码 通过maven指令安装模块到本地仓库(install指令) 在pom.xml中导入坐标执行maven的install命令将模块安装到本地maven仓库 团队内部开发可以发布模块功能到团队内部可共享的仓库中&#xff08;私服) 依赖管理 依赖指当前项目运行所需…...

第23篇:基础知识-Java Switch Case

switch case 语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。 switch case 语句语法格式如下: switch(expression){ case value : //语句 break; //可选 case value : //语句 break; //可选 //你可以有任意数量的…...

Go 实现多态和 参数的动态个数及动态类型

引子 go语言作为静态(编译期类型检测)强类型(手写代码进行类型转换)语言, 要想实现 动态语言的鸭子类型的调用方法,做到 一个入参是不同类型,还是有些麻烦的; 需求 希望写代码时像python一样的鸭子类型,不用管参数类型,都可以调用同一个方法;希望 入参像python一样 能够在 个…...

vue 指令

Vue 提供了很多指令&#xff0c;如&#xff1a;v-model, v-show&#xff0c;v-if等等&#xff0c;有利于应付开发时出现的各种情况。Vue 也提供了自定义指令&#xff0c;有利于开发者将某些通用性功能封装成一个指令&#xff0c;进行全局或局部注册。如&#xff1a;复制指令&am…...

APP违法违规收集使用个人信息合规评流程和范围

近期&#xff0c;工信部通报2023年第1批《侵害用户权益行为的APP通报》&#xff08;总第27批&#xff09;&#xff0c;共通报46款APP&#xff08;SDK&#xff09;&#xff0c;这些被责令限期整改的APP&#xff08;SDK&#xff09;&#xff0c;涉及的问题主要包括3个方面&#x…...

【力扣2379】 得到 K 个黑块的最少涂色次数(c++100%)

给你一个长度为 n 下标从 0 开始的字符串 blocks &#xff0c;blocks[i] 要么是 W 要么是 B &#xff0c;表示第 i 块的颜色。字符 W 和 B 分别表示白色和黑色。给你一个整数 k &#xff0c;表示想要 连续 黑色块的数目。每一次操作中&#xff0c;你可以选择一个白色块将它 涂成…...

[2.2.2]进程调度的时机、方式、切换与过程

文章目录第二章 进程管理进程调度的时机、方式、切换与过程&#xff08;一&#xff09;进程调度的时机&#xff08;二&#xff09;进程调度的方式&#xff08;三&#xff09;进程的切换与过程小结第二章 进程管理 进程调度的时机、方式、切换与过程 时机 什么时候需要进程调度…...

第24篇:Java包装类知识深度分析

目录 1、包装类背景 2、包装类的优点 3、包装类与基本类型关系 4、代码示例...

OpenClaw+GLM-4.7-Flash:学术论文辅助写作全流程

OpenClawGLM-4.7-Flash&#xff1a;学术论文辅助写作全流程 1. 为什么需要AI辅助学术写作 作为一名经常需要撰写学术论文的研究者&#xff0c;我深刻体会到写作过程中的痛点。从海量文献中筛选关键信息、整理参考文献格式、反复修改论文结构&#xff0c;这些工作往往耗费大量…...

基于vue+springboot框架的社区居民诊疗健康管理系统设计与实现

目录技术选型与架构设计核心功能模块划分开发阶段规划关键问题解决方案测试与部署文档规范项目技术支持源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作技术选型与架构设计 前端框架&#xff1a;Vue 3&#xff08;Composition API&#xff…...

QMCDecode:免费解锁QQ音乐加密文件的终极解决方案

QMCDecode&#xff1a;免费解锁QQ音乐加密文件的终极解决方案 【免费下载链接】QMCDecode QQ音乐QMC格式转换为普通格式(qmcflac转flac&#xff0c;qmc0,qmc3转mp3, mflac,mflac0等转flac)&#xff0c;仅支持macOS&#xff0c;可自动识别到QQ音乐下载目录&#xff0c;默认转换结…...

Mars3D实战:5分钟搞定GIS地图可视化开发(附完整代码示例)

Mars3D实战&#xff1a;5分钟搞定GIS地图可视化开发&#xff08;附完整代码示例&#xff09; 当GIS开发者第一次接触Mars3D时&#xff0c;最迫切的需求往往不是理解底层原理&#xff0c;而是快速实现一个可运行的地图可视化demo。本文将用厨房烹饪式的直白语言&#xff0c;带你…...

vSphere环境安全指南:使用vCenter创建受限用户的最佳实践

vSphere环境安全指南&#xff1a;精细化权限管理实战 在虚拟化基础设施管理中&#xff0c;vSphere环境的安全性直接关系到企业核心业务的稳定运行。作为高级管理员&#xff0c;我们常常面临一个两难选择&#xff1a;既要确保团队成员能够高效完成工作&#xff0c;又要防止过度授…...

10分钟搭建FunASR智能语音点餐系统:餐饮服务革命性升级指南

10分钟搭建FunASR智能语音点餐系统&#xff1a;餐饮服务革命性升级指南 FunASR是一个开源的端到端语音识别工具包&#xff0c;提供了SOTA预训练模型&#xff0c;能够帮助开发者快速构建语音交互应用。本文将详细介绍如何在10分钟内利用FunASR搭建智能语音点餐系统&#xff0c;…...

实战:在无商店的Win10企业版ThinkPad上,通过PowerShell手动部署Lenovo Vantage

1. 为什么需要手动部署Lenovo Vantage 很多ThinkPad用户可能都遇到过这样的困扰&#xff1a;新装的Windows 10企业版系统找不到微软应用商店&#xff0c;而Lenovo Vantage这个必备的管理工具又只能通过商店安装。作为一个长期使用ThinkPad的技术博主&#xff0c;我完全理解这种…...

4个步骤掌握FederatedScope:从入门到实践的联邦学习全流程指南

4个步骤掌握FederatedScope&#xff1a;从入门到实践的联邦学习全流程指南 【免费下载链接】FederatedScope An easy-to-use federated learning platform 项目地址: https://gitcode.com/gh_mirrors/fe/FederatedScope 联邦学习作为隐私计算领域的核心技术&#xff0c;…...

Insights Imaging 安徽医科大学第一附属医院放射科吴兴旺教授等团队:基于自动化nnU-Net与影像组学的胃癌Lauren分型术前预测

01文献学习今天分享的文献是由安徽医科大学第一附属医院放射科吴兴旺教授团队联合南京医科大学第二附属医院、中国科学技术大学附属第一医院等团队于2025年2月在《Insights into Imaging》&#xff08;中科院2区top&#xff0c;IF4.5&#xff09;上发表的研究“Preoperative pr…...

Notepad--:跨平台文本编辑器的技术架构与国产化实践

Notepad--&#xff1a;跨平台文本编辑器的技术架构与国产化实践 【免费下载链接】notepad-- 一个支持windows/linux/mac的文本编辑器&#xff0c;目标是做中国人自己的编辑器&#xff0c;来自中国。 项目地址: https://gitcode.com/GitHub_Trending/no/notepad-- Notepa…...