亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

useEffect如何通過form.getFieldValue(‘xxx‘)監(jiān)聽Form表單變化

 更新時(shí)間:2024年03月13日 15:56:18   作者:小劉加油!  
這篇文章主要介紹了useEffect如何通過form.getFieldValue(‘xxx‘)監(jiān)聽Form表單變化問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

場(chǎng)景

子組件中,某一個(gè)表格的數(shù)據(jù)需要依賴于上級(jí)組件的某一個(gè)表單元素值進(jìn)行計(jì)算。

毫無疑問,首先想到的肯定是監(jiān)聽 form 表單中元素的值,使用 useEffect 監(jiān)聽表單的變化,當(dāng)值發(fā)生變化時(shí),重新計(jì)算渲染。

首先說下我的代碼結(jié)構(gòu):

Form 表單是一個(gè)子組件,表格組件也是一個(gè)子組件,且是比較深的子組件(包含在tab標(biāo)簽頁下)。如果說 Form子組件是一級(jí)子組件,那么表格組件就是一個(gè)四級(jí)子組件。

在這種多層嵌套下,如何把 form 數(shù)據(jù)傳遞給對(duì)應(yīng)的表格子組件?

毫無疑問,選擇使用:useContext

在頂層組件中通過 Form.useForm() 定義 Form 實(shí)例,管理數(shù)據(jù)狀態(tài),通過 <context.Provider value={}></context.Provider>傳遞,表單子組件和表格子組件都可進(jìn)行接收。

不過在子組件監(jiān)聽代碼寫好后,卻發(fā)現(xiàn)了一個(gè)比較尷尬的問題:

表單元素的值發(fā)生了改變,但子組件的useEffect 卻沒能監(jiān)聽到。

// 子組件
import React, { useContext } from 'react'
import context from 'xxx/xxx'

const { form } = useContext<any>(context)

useEffect(() => {
	console.log('監(jiān)聽到了變化')
	// 下面是具體的邏輯
}, [form.getFiledValue('xx')])

注意:

當(dāng)時(shí)令我困惑的是:

當(dāng) Form 表單組件的某個(gè)表單元素值改變時(shí),雖然子組件 useEffect 沒有監(jiān)聽到變化,但通過表格子組件的輸入框的 onBlur 事件,調(diào)用 form.getFiledValue('xx'),卻可以拿到最新的值。

分析

需求終歸還是要往下開發(fā)的,監(jiān)聽不了,那就想辦法監(jiān)聽!

在項(xiàng)目中,我是使用了 const [form] = Form.useForm(); 來創(chuàng)建 Form 實(shí)例,管理表單數(shù)據(jù)狀態(tài),這也是函數(shù)式組件推薦的一種方式。

通過使用 useForm ,會(huì)讓表單成為 非受控組件,不用通過 useState 創(chuàng)建state 來維護(hù)數(shù)據(jù)。

而且 ant 官網(wǎng) 里面也說了:使用這種方式與其他獲取數(shù)據(jù)的方式的區(qū)別:

Form 僅會(huì)對(duì)變更的 Field 進(jìn)行刷新,從而避免完整的組件刷新可能引發(fā)的性能問題,因而無法在 render 階段通過 form.getFieldsValue 來實(shí)時(shí)獲取字段值。

看到這里,其實(shí)已經(jīng)很清楚了,因?yàn)?使用了 useForm,導(dǎo)致表單變成了 非受控組件,不能通過 useState 來創(chuàng)建 state 維護(hù)數(shù)據(jù),只能通過

form.getFieldsValue() / form.setFieldsValue() 

來獲取及設(shè)置表單數(shù)據(jù),ant design 官方文檔也有介紹。所以在這種情況下, 使用 useEffect 監(jiān)聽不到 form 表單的變化。

換句話說:

form.getFieldValue('xxx'); 

并不是響應(yīng)式的,由其取到的值,并不會(huì)觸發(fā) UI 更新,即:它不是一個(gè) state。 

不過,可能有人會(huì)問:我之前也使用過 useEffect 來監(jiān)聽 form.getFieldValue(‘xxx’),UI也能正常渲染啊,你這里是不是說錯(cuò)了?

答: 沒有說錯(cuò),我自己之前也有這樣的疑問,也遇到過這類問題。

在實(shí)際項(xiàng)目中,一個(gè) react 組件的 re-render 次數(shù)是不可控的, 特別是代碼寫的不那么規(guī)范的時(shí)候,

所以,當(dāng)看到 UI 更新的時(shí)候,或許是在新的 re-render 中被連帶著更新了;

又或許是項(xiàng)目代碼中 Form組件既使用了 form = {form} 屬性,又使用了 initialValues 屬性。

如下所示:

//
const [form] = Form.useForm();

<Form initialValues={formData} form={form} ref={formRef}> </Form>

解決方案

方案1

ant design @4.20 版本推出了一個(gè)新特性:Form.useWatch,可以直接獲取 form 中字段對(duì)應(yīng)的值,應(yīng)該是可以監(jiān)聽到的,具體用法可以參考官網(wǎng),這里不多做贅述。

可是 4.2 版本后才支持,我的項(xiàng)目版本是 4.12.3,暫不支持這個(gè)hooks,部門領(lǐng)導(dǎo)也不讓進(jìn)行 ant 升級(jí),所以就沒有嘗試這種寫法。

而且使用這種方法,固然可以監(jiān)聽到,不過性能不是太好,不建議使用。

因?yàn)樗鼤?huì)觸發(fā)整個(gè)組件的 re-render,當(dāng)組件比較大且監(jiān)聽 input 實(shí)時(shí)輸入時(shí),性能消耗就很恐怖。

方案2

拒絕使用 Form.useForm(),使用 initialValues 屬性,是表單變成一個(gè)可控組件,擁有 state,就可以正常監(jiān)聽。

不過對(duì)于我的項(xiàng)目代碼來說,改動(dòng)量太大,不劃算。

方案3

使用 useState 額外定義個(gè) state ,當(dāng)表單元素值發(fā)生變化時(shí),使用 setState(),然后將其值通過 context.Provider傳遞,在子組件監(jiān)聽。

方案4

使用 useReducer

useReduceruseState 都是用來存儲(chǔ)和更新 state,相當(dāng)于 useState 的升級(jí)版。

當(dāng) type 數(shù)量較多時(shí),建議使用 useReducer

方案5

Ant Plus 5 的 Watch 組件

專門用于監(jiān)聽表單字段變化,并更新局部UI。(沒嘗試過)

總結(jié)

其實(shí)核心要點(diǎn)就一句話:

Form 內(nèi)置方法,不是響應(yīng)式的(即不是一個(gè)state),由其設(shè)置或者獲取的值,不會(huì)觸發(fā)UI更新,只能對(duì)變更的field進(jìn)行刷新。

想要對(duì)其進(jìn)行監(jiān)聽也很簡(jiǎn)單,將其變成一個(gè)state即可。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 使用React組件編寫溫度顯示器

    使用React組件編寫溫度顯示器

    這篇文章主要為大家詳細(xì)介紹了使用React組件編寫溫度顯示器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • react國(guó)際化react-intl的使用

    react國(guó)際化react-intl的使用

    這篇文章主要介紹了react國(guó)際化react-intl的使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • react通過組件拆分實(shí)現(xiàn)購(gòu)物車界面詳解

    react通過組件拆分實(shí)現(xiàn)購(gòu)物車界面詳解

    這篇文章主要介紹了react通過組件拆分來實(shí)現(xiàn)購(gòu)物車頁面的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • reactrouter dom庫作用小結(jié)

    reactrouter dom庫作用小結(jié)

    `react-router-dom`是React應(yīng)用中用于實(shí)現(xiàn)頁面導(dǎo)航、嵌套路由、布局管理以及代碼分割和懶加載的重要庫,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-11-11
  • 在react中使用windicss的問題

    在react中使用windicss的問題

    這篇文章主要介紹了在react中使用windicss的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • react清空ant.design中表單內(nèi)容的方法實(shí)現(xiàn)

    react清空ant.design中表單內(nèi)容的方法實(shí)現(xiàn)

    本文主要介紹了react清空ant.design中表單內(nèi)容的方法實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-12-12
  • React Router V6更新內(nèi)容詳解

    React Router V6更新內(nèi)容詳解

    這篇文章主要為大家介紹了React Router V6更新內(nèi)容,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • React實(shí)現(xiàn)簡(jiǎn)單登錄的項(xiàng)目實(shí)踐

    React實(shí)現(xiàn)簡(jiǎn)單登錄的項(xiàng)目實(shí)踐

    登錄、注冊(cè)、找回密碼是前端項(xiàng)目經(jīng)常遇到的需求,本文主要介紹了React實(shí)現(xiàn)簡(jiǎn)單登錄的項(xiàng)目實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • React項(xiàng)目中應(yīng)用TypeScript的實(shí)現(xiàn)

    React項(xiàng)目中應(yīng)用TypeScript的實(shí)現(xiàn)

    TypeScript通常都會(huì)依賴于框架,例如和vue、react 這些框架結(jié)合,本文就主要介紹了React項(xiàng)目中應(yīng)用TypeScript的實(shí)現(xiàn),分享給大家,具體如下:
    2021-09-09
  • React的diff算法核心復(fù)用圖文詳解

    React的diff算法核心復(fù)用圖文詳解

    這篇文章主要為大家介紹了React的diff算法核心復(fù)用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08

最新評(píng)論