為什么說form元素是React的未來
思考一個問題
如果有一個HTML
標(biāo)簽,React
圍繞他專門出了2個hook
,那這個標(biāo)簽對React
未來的發(fā)展一定非常重要,這沒毛病吧?
這個標(biāo)簽就是 —— form
。
React
圍繞form
新出了如下2個hook
:
useOptimistic
useFormStatus
Next.js的發(fā)展歷程
說到React
未來的發(fā)展,必須從Next.js
聊起。畢竟,React
團(tuán)隊成員不是加入Next
團(tuán)隊,就是在加入的路上。
web
開發(fā)中涉及到前后端交互的部分主要包括:
- 根據(jù)后端數(shù)據(jù)渲染前端頁面
- 根據(jù)前端用戶輸入保存數(shù)據(jù)到后端
Next.js
的發(fā)展主要圍繞以上兩點展開。
根據(jù)后端數(shù)據(jù)渲染前端頁面
前期,Next.js
的主打特性是SSR
、SSG
。也就是把根據(jù)后端數(shù)據(jù)渲染前端頁面的過程從前端挪到后端。
這個時期的Next.js
路由被稱為Pages Router
。
時間來到Next.js v13
,以RSC
(React Server Component)為核心的App Router
取代Pages Router
成為默認(rèn)配置。
很多朋友不熟悉RSC
,認(rèn)為他是實驗特性。實際上,RSC
借由Next.js
已經(jīng)落地了。
一句話理解RSC
—— 客戶端組件(在瀏覽器渲染的React
組件)可以根據(jù)依賴分為兩部分:
- 依賴數(shù)據(jù)源(比如數(shù)據(jù)庫、文件系統(tǒng))的組件,可以作為
RSC
(服務(wù)端組件) - 依賴狀態(tài)(比如
state
、props
、context
)的組件,可以作為客戶端組件
從根據(jù)后端數(shù)據(jù)渲染前端頁面角度看:
SSR
、SSG
是頁面級別的(服務(wù)端渲染呈現(xiàn)的是整個頁面)RSC
是組件級別的(服務(wù)端組件請求數(shù)據(jù)源)
根據(jù)前端用戶輸入保存數(shù)據(jù)到后端
聊完了根據(jù)后端數(shù)據(jù)渲染前端頁面,那么,圍繞根據(jù)前端用戶輸入保存數(shù)據(jù)到后端,Next.js
能做哪些優(yōu)化?
這就要提到Next.js
的實驗特性 —— Server Action
。
Server Action
根據(jù)前端用戶輸入保存數(shù)據(jù)到后端的常見場景是表單提交,通常我們會在form
的obSubmit
事件中做后續(xù)處理:
function Form() { function submit() { // ...處理formData的邏輯 // ...發(fā)送請求的邏輯 } return ( <form onSubmit={submit}> <input type="text"/> <input type="text"/> </form> ) }
以上代碼有什么可改進(jìn)的地方呢?
從用戶體驗的角度看,如果前端禁用了JS
,那么React
不能運(yùn)行,上述交互失效。如果在禁用JS
的情況下也能提交表單就好了。
從開發(fā)體驗的角度看,submit
方法會發(fā)起請求,后端再根據(jù)請求攜帶的formData
操作數(shù)據(jù)庫,比較繁瑣。如果在submit
方法內(nèi)能直接操作數(shù)據(jù)庫就好了。
Server Action
特性就是為了實現(xiàn)以上2個目標(biāo)。
首先來看第一個目標(biāo)。
目標(biāo)1
HTML
原生的form
元素有個action
屬性,可以接收一個url
。當(dāng)提交表單(比如點擊type
為submit
的按鈕)后formData
會提交給該url
。
<form action="/action_page.php" method="get"> <label for="fname">First name:</label> <input type="text" id="fname" name="fname"><br><br> <label for="lname">Last name:</label> <input type="text" id="lname" name="lname"><br><br> <input type="submit" value="Submit"> </form>
由于提交表單的行為是HTML
原生支持的,所以在禁用JS
的情況下也能執(zhí)行。
這就是禁用JS
也能提交表單的理論基礎(chǔ)。
目標(biāo)2
React
擴(kuò)展了form
的action
屬性,讓他除了支持url
,還能支持回調(diào)函數(shù),比如:
function App() { function submit(data) { // ... } return ( <form action={submit}> <! -- 省略 --> </form> );
如果這個回調(diào)函數(shù)內(nèi)是前端執(zhí)行的邏輯,則被稱為client action
,比如下面這樣:
async function submit(data) { await const res = saveData(data); // ... }
如果這個函數(shù)內(nèi)是后端執(zhí)行的邏輯,則被稱為server action
,比如下面這樣:
"use server" async function submit(data) { const userID = cookies().get("userID")?.value; await db.users.update(userID, data); // ... }
"use server"
標(biāo)記代表這是個server action
。
如果是server action
,那么發(fā)起的請求類型是multipart/form-data
(即表單提交):
響應(yīng)類型則是RSC協(xié)議
:
也就是說,有了server action
,開發(fā)者可以直接在form
的action
屬性(或者button
的formAction
屬性等其他幾種屬性)內(nèi)書寫后端邏輯,并且在瀏覽器禁用JS
的情況下這些邏輯也能執(zhí)行。
2個新hook
為了更好的服務(wù)server action
,React
團(tuán)隊新出了2個hook
用于提高form
場景下的用戶體驗:
useOptimistic
useFormStatus
當(dāng)前,這2個hook
的介紹只能在Next.js文檔(而不是React
文檔)中看到。
useOptimistic
主要用來優(yōu)化提交數(shù)據(jù)的用戶體驗。
比如,在點贊的場景,通常邏輯是:
- 點擊點贊按鈕
- 發(fā)起點贊請求
- 點贊成功,前端顯示點贊效果
但為了用戶體驗的流暢,前端通常會把邏輯做成:
- 點擊點贊按鈕
- 前端顯示點贊效果(同時發(fā)起點贊請求)
- 根據(jù)請求結(jié)果,如果點贊成功則不做處理,如果點贊失敗則重置按鈕
useOptimistic
的本質(zhì)就是在狀態(tài)層面實現(xiàn)上述效果。
useFormStatus
則用于在表單提交過程中顯示pending
狀態(tài):
function ButtonDisabledWhilePending({action, children}) { const {pending} = useFormStatus(); return ( <button disabled={pending} formAction={action}> {children} </button> ); }
有同學(xué)可能會疑惑:useFormStatus
沒有傳參,他怎么知道對應(yīng)哪個form
?
實際上,為了實現(xiàn)useFormStatus
,React
在源碼內(nèi)為所有HostComponent
(即原生HTML
元素對應(yīng)組件,比如<div/>
)定制了一個context
。
當(dāng)某個form
觸發(fā)表單提交時,context
的值會被更新為這個form
的數(shù)據(jù)。useFormStatus
本身僅僅是useContext(上述context)
。
總結(jié)
可以發(fā)現(xiàn),不管是useFormStatus
、useOptimistic
還是最近1~2年新出的hook
(比如useId
、useMutableSource
),我們開發(fā)者都很少會用到。
因為這些hook
都是為上層框架(主要是Next.js
)提供的。
React
早已完成他作為前端框架的使命。在他生命的后半程,他將作為上層框架的操作系統(tǒng)而存在。
server action
是Next.js
的未來,Next.js
是React
的未來。所以,React
的未來會圍繞form
元素持續(xù)布局。
以上就是form元素是React的未來的詳細(xì)內(nèi)容,更多關(guān)于form元素是React的未來的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用react-virtualized實現(xiàn)圖片動態(tài)高度長列表的問題
一般我們在寫react項目中,同時渲染很多dom節(jié)點,會造成頁面卡頓, 空白的情況。為了解決這個問題,今天小編給大家分享一篇教程關(guān)于react-virtualized實現(xiàn)圖片動態(tài)高度長列表的問題,感興趣的朋友跟隨小編一起看看吧2021-05-05React實現(xiàn)createElement 和 cloneElement的區(qū)別
本文詳細(xì)介紹了React中React.createElement和React.cloneElement兩種方法的定義、用法、區(qū)別及適用場景,具有一定的參考價值,感興趣的可以了解一下2024-09-09ahooks封裝cookie?localStorage?sessionStorage方法
這篇文章主要為大家介紹了ahooks封裝cookie?localStorage?sessionStorage的方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07如何使用 React Router v6 在 React 中
面包屑在網(wǎng)頁開發(fā)中的角色不可忽視,它們?yōu)橛脩籼峁┝艘环N跟蹤其在網(wǎng)頁中當(dāng)前位置的方法,并有助于網(wǎng)頁導(dǎo)航,本文介紹了如何使用react-router v6和bootstrap在react中實現(xiàn)面包屑,感興趣的朋友一起看看吧2024-09-09