React 表單太卡?也許你用錯了控制方式

🎙 歡迎來到《前端達人 · 播客書單》第 23 期。

視頻版(播客風格更精彩)

今天我們聚焦一個「寫前端永遠逃不掉」的主題:表單處理。 你有沒有遇到過這些問題:

  • 表單怎么一改就卡?state 是不是用錯了?

  • 有時候 value 控不住輸入框,直接報錯?

  • 面試被問“受控和非受控的區別”,說不清楚?

別急,這一期我們就用真實例子 + 背后原理,一次性理清楚 React 中的表單處理邏輯,帶你站在更工程化的視角看表單。

一、問題導入:React 的表單處理,為什么需要重新發明輪子?

在原生 HTML 中,表單元素(比如?<input>)自帶內部狀態:

你填了什么,瀏覽器記著;你點了提交,瀏覽器打包給后端。

但到了 React,“組件狀態要統一由你來掌控”,這就帶來一個問題:

🔄 要不要把?<input>?的值也交給組件 state 管?

這時候你就面臨選擇:

做法

特點

受控組件

React 負責存 & 改值,value 受 state 控制

非受控組件

瀏覽器 DOM 自己管理,React 只負責“拿一下”

很多初學者會覺得“我只是個輸入框,哪來那么復雜”,但其實——寫 React 表單沒寫好,是最容易留下 bug 的地方之一。

二、核心定義:什么是受控字段、非受控字段?

📌?受控字段 Controlled Field

React 完全掌控字段值,配合?value?+?onChange?實現數據同步。

  • 每次用戶輸入,觸發?onChange?→ 調用?setState?更新值。

  • 下次 render 時,value={state}?將新值綁定回組件。

📌?非受控字段 Uncontrolled Field

React 不管輸入框的值,用瀏覽器默認行為,必要時通過?ref?獲取 DOM 節點來拿值。

  • 初始化用?defaultValue

  • 獲取用?ref.current.value

🧠 一句話總結:

Controlled 是“值存我這”,Uncontrolled 是“值你自己管”。

三、使用方式與典型代碼

? 受控組件代碼:

const?[name, setName] = useState('');<inputtype="text"value={name}onChange={e?=>?setName(e.target.value)}
/>

🔍 解釋:

  • value={name}:值由組件狀態決定

  • onChange:每次輸入更新組件 state

  • React 全程控制這個 input,數據同步準確、可控性強

? 非受控組件代碼:

const?nameRef = useRef();<input?type="text"?defaultValue="Tom"?ref={nameRef}?/><button?onClick={()?=>?alert(nameRef.current.value)}>提交
</button>

🔍 解釋:

  • 用?defaultValue?初始化值,只作用于第一次渲染

  • 后續輸入的值保存在 DOM 中

  • 提交按鈕用?ref.current.value?獲取當前值

四、工作機制:受控與非受控的背后原理

Controlled 的思路:React 的“統一狀態來源”原則

在 React 中,組件的 UI = 函數(state) 所以任何用戶行為,最終都應該反映到 state 上,形成閉環:

State → Render UI → onChange Event → Update State

🔁 每次輸入其實是兩次操作:

  1. 用戶輸入觸發?onChange

  2. 我們手動用?setState?改值,再 render 回去

雖然多了一步,但換來了:

??狀態統一管理

??更容易 debug 和回溯

??便于聯動邏輯(如禁用按鈕、動態校驗)

Uncontrolled 的思路:用瀏覽器原生行為節省性能

它就像「只讀收件箱」:

  • 你不監聽每一個字怎么輸入

  • 你只關心“用戶最終輸入了什么”

適用于這種場景:

  • 你只在點擊「提交」時需要值

  • 不需要做任何即時 UI 反饋

五、典型應用場景分析

場景

推薦寫法

理由

用戶注冊、登錄

Controlled

需要實時反饋和驗證

文件上傳

Uncontrolled

<input type="file">

?是只讀字段

表單僅用于一次性收集值

Uncontrolled

節省性能

表單字段需要與其他組件狀態聯動

Controlled

更可維護

使用 React Hook Form

Controlled + ref混合

更高效的封裝形式

💡 文件上傳字段是一個經典案例:

<input type="file"?ref={fileRef} />

為什么不能用受控寫法? 因為?<input type="file">?的?value?是只讀的!

六、易錯點提示 ??

? 新手常見誤區:

<input value="abc"?/>

不綁定?onChange?就寫?value,React 會警告你:你讓它受控了,但不給它機會改變!

? 正確做法:

const?[value, setValue] = useState('abc');
<input?value={value}?onChange={e?=>?setValue(e.target.value)} />

? 常見對比總結:

項目

受控字段

非受控字段

控制權

React state

DOM 自身

使用場景

表單聯動、即時校驗

簡單提交、上傳文件

性能

會觸發重新渲染

不依賴組件更新

調試性

更容易統一 debug

值存 DOM,調試成本高

七、總結復盤 🧠

  • 🎯 受控字段:優先使用,適合一切中大型表單

  • ?? 非受控字段:在“只讀、輕量、特殊場景”中可以使用

  • 🔄 Controlled 代表 React 哲學,Uncontrolled 保留 HTML 本能

  • 🚧 避免 value 無 onChange;避免 file 字段用 state 控制

  • 🔁 兩者可以混合使用,尤其在大型表單組件中(如 React Hook Form)

🎯 下期預告

下一期,我們將上手使用社區最火的表單庫之一 ——?React Hook Form,帶你感受表單處理的極致簡潔。

#React? ?#React播客??#前端播客??#前端達人??#TypeScript?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/911721.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/911721.shtml
英文地址,請注明出處:http://en.pswp.cn/news/911721.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

`customRef` 在實戰中的使用:防抖、計算屬性緩存和異步數據獲取

&#x1f90d; 前端開發工程師、技術日更博主、已過CET6 &#x1f368; 阿珊和她的貓_CSDN博客專家、23年度博客之星前端領域TOP1 &#x1f560; 牛客高級專題作者、打造專欄《前端面試必備》 、《2024面試高頻手撕題》、《前端求職突破計劃》 &#x1f35a; 藍橋云課簽約作者、…

騰訊混元3D制作角色模型的教程-3

騰訊混元3D中實現角色骨骼綁定與動畫生成的詳細操作指南,結合官方功能說明及實操要點整理: ?? 一、前期準備:模型要求 角色姿態規范 僅支持標準T-pose(大字型站立) 的全身人物模型(如卡通角色)。 非標準姿態或非人形模型(如動物、道具)暫不支持自動綁骨。 模型來源…

React 和 Vue 項目中集成基于 Svelte 的 `Bytemd` 庫 || @bytemd/react` 底層實現原理

Bytemd 并使用Svelte 框架編寫的。Svelte 是一種不同的前端框架&#xff0c;它的核心思想是在編譯時將組件代碼轉換成高效、原生 JavaScript&#xff0c;從而避免運行時虛擬 DOM 的開銷。 理解了這一點&#xff0c;我們就可以深入探討如何在 React 和 Vue 項目中適配 Svelte 編…

【新品解讀】高性能緊湊型 RFSoC FPGA 開發平臺 AXW22,重塑射頻開發體驗

如果您正在煩惱如何在有限的物理空間和預算內&#xff0c;依然實現卓越的射頻帶寬與處理能力&#xff0c;ALINX 基于 AMD RFSoC FPGA 開發板 AXW22 正是為您準備的。 &#xff08;AMD Zynq UltraScale RFSoC FPGA 射頻開發平臺 AXW22&#xff09; 和所有 RFSoC 平臺一樣&#…

Spring @ModelAttribute注解全解析:數據綁定與模型管理

Spring 的 @ModelAttribute 注解主要用于數據綁定和模型屬性管理,支持方法級別和參數級別的應用,以下是其核心特性和使用場景: ?? 一、核心功能 數據綁定 將 HTTP 請求參數(如表單字段、查詢參數)自動綁定到 Java 對象。支持從請求參數、URI 路徑變量、請求頭等多來源獲…

[project-based-learning] 開源貢獻指南 | 自動化鏈接驗證 | Issue模板規范

第四章&#xff1a;貢獻指南 歡迎回來&#xff01;在上一章《項目分類體系》中&#xff0c;我們探討了README.md文件如何通過編程語言和子類別組織教程&#xff0c;從而提升檢索效率。 現在已了解教程列表的構成&#xff08;《教程列表》&#xff09;、條目編寫規范&#xff…

OSCP備戰-LordOfTheRoot靶機復現步驟

PDF下載&#xff1a; Target-practice/Range at main szjr123/Target-practice 一、靶機描述 靶機地址&#xff1a;https://www.vulnhub.com/entry/lord-of-the-root-101,129/ 靶機難度&#xff1a;中等&#xff08;CTF&#xff09; 靶機描述&#xff1a;這是KoocSec為黑…

蘋果或140億美元收購Perplexity,AI搜索格局面臨重構

據多家媒體報道&#xff0c;蘋果內部高管近期就競購AI初創公司Perplexity的可能性舉行了初步會談。若交易最終達成&#xff0c;可能將以接近140億美元的估值完成&#xff0c;成為蘋果歷史上最大規模的收購案12。盡管討論仍處于早期階段&#xff0c;且蘋果尚未與Perplexity管理層…

屠龍刀策略

該策略是一個針對金融市場的自動化交易策略,主要用于日內交易,特別關注于在中國金融期貨市場(如滬深300指數期貨(IF))的日間交易時段(09:20至15:15)進行操作。下面是該策略核心部分的代碼注解解析: 參數定義 - `Nnn1(5)` 和 `Nnn2(20)`:策略中的兩個參數,用于內部計…

【本機已實現】使用Mac部署Triton服務,使用perf_analyzer、model_analyzer

我們的目標是星辰大海 硬件配置&#xff1a;Apple M224 GB Tirtion實現過程 1??Docker安裝 Tirtion的實現&#xff0c;首先要確保系統上的Docker可用 使用默認源會導致拉取失敗&#xff0c;因為墻 Error response from daemon: Get "https://registry-1.docker.io/v2…

idea依賴下載慢解決

setttings.xml <mirrors><mirror><id>aliyunmaven</id><name>阿里云公共倉庫</name><url>https://maven.aliyun.com/repository/public</url><mirrorOf>*</mirrorOf> <!-- 匹配所有倉庫請求 --></mirr…

C# WPF常用調試工具匯總

除了Live Visual Tree、Live Property Explorer和Snoop外&#xff0c;WPF開發還有多種強大的調試工具。以下是完整的工具集合及其詳細使用方法&#xff1a; 1. WPF Performance Suite (WPF性能分析套件) 簡介 微軟官方提供的專業WPF性能分析工具&#xff0c;包含多個組件用于診…

《Vuejs設計與實現》第 11 章(快速 diff 算法

目錄 11.1 相同的前置元素和后置元素 11.2 判斷是否需要進行 DOM 移動操作 11.3 如何移動元素 11.4 總結 我們將探討第三種用于比較新舊子節點集合的方法&#xff1a;快速Diff算法。 這種算法的速度非常快&#xff0c;最早應用于 ivi 和 inferno 框架&#xff0c;DOM 操作方…

JavaScript 存儲對象 sessionStorage (會話存儲) 和 localStorage(本地存儲)

深入理解 localStorage localStorage 是瀏覽器提供的一種客戶端存儲機制&#xff0c;用于在用戶瀏覽器中存儲鍵值對數據。與 cookie 相比&#xff0c;它提供了更大的存儲容量&#xff08;通常為 5-10MB&#xff09;&#xff0c;并且不會隨 HTTP 請求發送到服務器&#xff0c;因…

Z-Ant開源程序是簡化了微處理器上神經網絡的部署和優化

?一、軟件介紹 文末提供程序和源碼下載 Z-Ant &#xff08;Zig-Ant&#xff09; 是一個全面的開源神經網絡框架&#xff0c;專門用于在微控制器和邊緣設備上部署優化的 AI 模型。Z-Ant 使用 Zig 構建&#xff0c;為資源受限的硬件上的模型優化、代碼生成和實時推理提供端到端…

Linux系統---Nginx配置nginx狀態統計

配置Nignx狀態統計 1、下載vts模塊 https://github.com/vozlt/nginx-module-vts [rootclient ~]# nginx -s stop [rootclient ~]# ls anaconda-ks.cfg nginx-1.27.3 ceph-release-1-1.el7.noarch.rpm nginx-1.27.3.tar.gz info.sh …

深入理解 C++ Lambda表達式:四大語法特性 + 六大高頻考點全解析

Lambda表達式是C11引入的一項重要特性&#xff0c;它極大地改變了我們編寫匿名函數的方式。 一、為什么會有Lambda表達式 在C11之前&#xff0c;當我們需要傳遞一個簡單的函數時&#xff0c;通常有以下幾種選擇&#xff1a; 1.1、定義一個單獨的函數 // 單獨定義的比較函數…

SpringBoot 自動化部署實戰:CI/CD 整合方案與避坑全指南

在數字化轉型浪潮席卷全球的當下&#xff0c;企業對軟件交付的速度與質量提出了前所未有的高要求。SpringBoot 憑借其 “約定優于配置” 的特性&#xff0c;成為 Java 領域快速構建應用的熱門框架。而將 SpringBoot 與 CI/CD&#xff08;持續集成 / 持續交付&#xff09;相結合…

JVM字節碼文件結構深度剖析

反匯編&#xff0c;以下命令可以查看相對可讀的詳細結構 javap -verbose ByteCode.class與Class二進制文件并不是直接對齊的 Class二進制文件結構參照表 ClassFile {u4 magic;魔數u2 minor_version;副版本號u2 major_version;主版本號u2…

跟著chrome面板優化頁面性能

沒有優化前&#xff1a; 1.對文本進行壓縮&#xff1a; 重新打包 運行 評分好像還是沒有發生改變&#xff0c;于是我去找別的壓縮的途徑&#xff0c; npm install --save-dev vite-plugin-compression 然后修改vite.config.js文件 導入compression插件 文件夾中也成功出現了…