成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

React 支持 Form Action 是在作妖?不,它是一種重磅回歸

開發 前端
React form Action 是一個很小的知識點,但是它代表的是表單開發的另一種思路,是一種開發方式的隆重回歸。因此這要求我們對 HTML 本身已經支持的表單能力要有所了解。我們在后續的開發使用中,會逐漸弱化受控組件的使用,這會帶來開發體驗和性能上的提升。

這是一個超強的特性。仔細看完你就能體會。

在 html 的基礎知識中,表單是很重要的一個環節。但是由于各種原因,原生的表單開發方式相關知識被部分前端開發所遺忘,他們對 form action,formdata 有一種陌生感。

因此,當看到有消息稱 React 19 支持了 form action 之后,許多前端感覺有點懵。不知道這是啥。這篇文章就先給大家科普一下相關的知識。

一、HTML form action

先來看一段簡單的代碼。

<form id="form" method="get">
  First name:
  <input type="text" value="Jake" name="fname">
  Last name:
  <input type="text" value="Ma" name="lname">
  <input type="submit" value="提交">
</form>

當我們使用表單 form 元素時,內部的表單元素可以根據 name 屬性與 value 值自動組合成一個完整的序列化表單對象。我們不再需要額外去拼接他們。

合成的序列化對象,我們稱之為 FormData, 這是一個特殊的對象。我們可以直接通過如下方式獲取到該對象。

let formdata = new FormData(form)

console.log(formdata.get('fname'))
console.log(formdata.get('lname'))

i

我們無法直接觀察到 FormData 的值,需要使用 .get 方法來獲取。

FormData 也可以被網絡請求支持,例如我們可以把 FormData 對象作為 fetch 請求的 body,直接發送。

form.onsubmit = async e => {
  e.preventDefault()
  
  const response = await fetch('/post/user', {
    method: 'POST',
    body: new FormData(form)
  })
  let res = await response.json()
  // do something
}

在這個案例中,當 type='submit' 的按鈕點擊提交時,onsubmit 就會觸發,我們可以在這個回調函數里執行自己的提交邏輯。

?

HTTP 中 content-type 字段有專門支持 FormData 的值,如下所示:

Content-Type: multipart/form-data

除此之外,我們可以使用 form 元素的 action 屬性來簡化提交。不過它的表現會不太一樣。

action 接收一個 URL 作為參數,可以是絕對路徑,也是可以相對路徑。它表示攜帶表單數據向該地址發送請求。默認情況下頁面會跳轉到指定的 URL 地址。

<form id="form" action="xx.html" method="post">
  First name:
  <input type="text" value="Jake" name="fname">
  Last name:
  <input type="text" value="Ma" name="lname">
  <input type="submit" value="提交">
</form>

服務端可以攔截該地址,并定義響應行為。

這樣做的好處就是我們可以簡化提交行為的代碼。無需使用 JavaScript 對邏輯進行任何額外的處理,就能完成一次提交操作。在沒有額外要求的情況下,我們可以非常方便的使用這種方式來提交表單數據,上傳文件等。

二、FormData 使用詳解

FormData API 如下圖所示。

我們可以先創建一個空的 FormData 對象,然后通過 append 方法來添加屬性。

const formdata = new FormData()
formdata.append('title', 'hello world')

也可以直接使用 form 元素對象進行初始化。并在子表單元素中合并具體的字段和值。

<form id="form" method="post">
  First name:
  <input type="text" value="Jake" name="fname">
  Last name:
  <input type="text" value="Ma" name="lname">
  <input type="submit" value="提交">
</form>
const formdata = new FormData(form)

我們可以通過 .get 方法獲取具體字段的值。在表單元素中,name 屬性表示字段名。

formdata.get('fname')

可以有多個同名的 name,因此 .get() 表示獲取第一個,.getAll() 表示獲取所有。

// 獲取所有 name 為 age 的字段,返回數組
formdata.getAll('age')

我們可以通過 .set 方法設置對應字段的值。如果字段名不存在,則添加該字段。

formdata.set('fname', 'Jake')

可以通過 .has(key) 來判斷是否存在某個字段。

formdata.has('fname') // true

可以通過 .delete(key) 刪除某一個字段。

formdata.delete('fname')

我們可以使用 formdata 來實現一個上傳文件的功能。

<form id="form">
  <input type="text" name="firstName" value="John">
  Picture:
  <input type="file" name="picture" accept="image/*">
  <input type="submit">
</form>
form.onsubmit = async e => {
  e.preventDefault()

  const response = await fetch('/post/file', {
    method: 'POST',
    body: new FormData(form)
  })
  let res = await response.json()
  // do something
}

可以明確的是,HTML 本身對 form 表單的支持非常強大與完整,它已經足以支撐我們開發大多數功能。React 19 進一步明確支持 form 表單,并非是一種作妖,而是一種回歸。

三、React Form Action

React 19 在表單上提供了更多充滿想象空間都 API,它們用好了非常爽,不過一個麻煩的事情是如果你通過自學,想要透徹理解并找到最佳實踐可能會非常困難。

這里最核心的原因是因為開發思維發生了比較徹底的變化,主要體現在 React19 在嘗試弱化受控組件的概念,嘗試引導開發者盡可能少的使用 useEffect,并且盡可能少的使用 useState 存儲數據。

拋開學習成本不談,我個人認為這是一個非常好的變化,新的開發方式上在開發體驗和性能表現上都有非常大的提升。它充分利用了 HTML 中表單元素本身已經支持的能力,例如表單驗證,自定義異常樣式,自定義錯誤信息等。

這里的學習成本主要來源于三個方面:

  • 許多前端開發對 HTML 表單組件本身的了解程度不夠。
  • 對 React 并發模式了解不夠。
  • 對 React 19 新 api 難以徹底消化。
  • 對表單開發的復雜場景認知不夠。

!

因此,許多前端開發在之前的表單開發中,掌握得都比較吃力。

不過沒關系,我們會盡量拆分去學習。確保大家都能讀有所得。這一章節就先簡單給大家介紹一下 React 在表單上的基礎表現。

?

先用最基礎的知識內容鋪墊一下。

在 HTML 的表單元素中,我們可以通過監聽 form 對象的 onsubmit 來回調函數的執行。也可以通過 action 屬性來直接向服務端發送請求。

在 React 19 中,form 元素支持的 action 在這個基礎之上發生了一些變化。它支持給 action 傳遞一個回調函數以供我們使用。該回調函數會將 FormData 作為參數傳入。我們可以通過這種方式拿到表單里的所有數據。

?

這個變化主要是 React 中并不提倡直接獲取元素對象,以及直接往后端發送請求的方式并不常用。

function action(formdata) {
  // do something   
}
<form action={action}>
  <input type="text" name="firstName" value="John">
  Picture:
  <input type="file" name="picture" accept="image/*">
  <input type="submit">
</form>

當我們點擊提交按鈕時,action 方法就會觸發執行。當然,我們也可以給 submit 一個 formAction 屬性來達到同樣的效果。

<form>
  <input type="text" name="firstName" value="John">
  Picture:
  <input type="file" name="picture" accept="image/*">
  <input formAction={action} type="submit">
</form>

i

默認情況下,當我們點擊提交之后,form 會自動清空內部的所有數據,如下圖所示:

i

如果你在設置了 action 的同時,又設置了 onSubmit 回調,那么 onSubmit 會優先執行。

四、案例

學習了這些基礎知識之后,我們來完成一個比較簡單的案例。我們在表單中輸入信息,并把信息記錄展示在一個列表中。案例演示效果如下

首先我們要定義一個數據,用于存儲列表。

const [posts, setPosts] = useState([])

然后在 jsx 中,定義一個表單內容,和列表渲染。

<div>
  <div>基礎的表單提交案例</div>

  <form action={action}>
    <div className="form_item">
      <div className="label">Title</div>
      <input name='title' type="text" placeholder='Enter title' />
    </div>

    <div className="form_item">
      <div className="label">Name</div>
      <input name='content' type="text" placeholder='Enter you name' />
    </div>

    <div className="form_item">
      <button className='primary' type='submit'>Submit</button>
    </div>
  </form>

  <ul className='_07_list'>
    {posts.map((post, index) => (
      <div key={`${post.title}-${index}`} className='_07_item'>
        <h2>{post.title}</h2>
        <p>{post.content}</p>
      </div>
    ))}
  </ul>
</div>

提交之后的邏輯在 action 中處理,action 回調函數能拿到最新的 formdata。然后把對應的數據拿出來,設置到 posts 里面即可。

function action(data) {
  const title = data.get('title')
  const content = data.get('content')

  if (title && content) {
    setPosts([...posts, {title, content}])
  }
}

我們可以簡單擴展一下,在這個基礎之上做一些校驗。我們把其中一個 input 做一些簡單的調整。

<input
  onInput={onInput}
  name='content'
  type="text"
  placeholder='Enter you name'
  required
  pattern={'abc'}
/>

在 css 中,新增如果校驗不通過的樣式。

input:invalid {
  border: 1px dashed red;
}

演示效果如下:

我們還可以通過 input 的 onInput 事件對驗證樣式進行自定義。

function onInput(event) {
  let input = event.target
  console.log(input.validity)
  if (input.validity.valid) {
    console.log('xxxxx', input.validity)
  }
}

這里面有許多狀態可以支持我們做許多自己的擴展。

五、它對服務端渲染的劃時代意義

這里大家需要注意的一個小細節就是,許多針對表單功能增強的 API,都不是從 react 中引入,而是從 react-dom 中引入。

第一時間我還沒想通這到底咋回事。感覺好奇怪。后來我才意識到,這對于服務端渲染有著巨大的劃時代的重要意義。

在評估網頁性能中,有一個重要的性能指標:TTI:可交互時間。頁面加載完成,并且首屏顯示,并且頁面可以交互。

但是,在以前的服務端渲染項目中,想要頁面元素可以被點擊,可交互,需要經歷一個重要的過程,那就是 Hydrate 水合。意思就是說,第一時間從服務端給到頁面上的只是字符串,并不具備可交互功能,它需要瀏覽器渲染之后,變成 DOM 元素,再通過 React 水合之后,再變成 React 組件,然后才可以正常點擊交互。

因此,React 服務端渲染項目雖然首屏直出理論上會快一些,但是 TTI 要多經歷一個水合的過程,那么可交互時間等待就比較久了。

?

其實也不一定,處理不好,服務端渲染項目也會更慢。

React 19 支持的 form action,實際上是極大的利用了瀏覽器的自帶的表單能力,它要可交互,并不需要經歷水合過程,瀏覽器渲染成 DOM 就可以正常交互了。

道友們,誰懂啊,這就有點厲害了。

?

有的服務端渲染項目首屏渲染時間只需要不到 1s,但是首次可交互時間,能長達 8s 之久。從這個簡單的數據對比,你就能領會不需要水合是多大的提升了。

這不僅在客戶端組件中,直接掙脫了之前受控組件在性能上的桎梏,還更進一步在服務端渲染項目有更強的體現。如果一旦跟 next.js 有機結合...

不得不佩服 React 團隊在設計項目架構解決方案上的超前思維。

六、總結

React form Action 是一個很小的知識點,但是它代表的是表單開發的另一種思路,是一種開發方式的隆重回歸。因此這要求我們對 HTML 本身已經支持的表單能力要有所了解。我們在后續的開發使用中,會逐漸弱化受控組件的使用,這會帶來開發體驗和性能上的提升。

除此之外,React 在表單開發中還提供了許多功能增強的 hook,我們在后續的分享慢慢學習。

責任編輯:姜華 來源: 這波能反殺
相關推薦

2015-01-21 15:35:58

開源

2015-08-03 09:36:01

賽迪翻譯

2015-08-31 09:27:21

語言界面UI

2012-01-17 11:02:39

2021-03-22 08:15:46

國企程序猿事業

2010-05-27 11:04:32

2023-05-31 07:29:46

2012-07-30 09:58:53

2012-11-01 13:41:25

編程語言BasicPerl

2016-04-18 13:41:10

軟件IC網

2015-03-13 11:23:21

編程編程超能力編程能力

2017-07-13 16:43:23

DevOps持續集成業務

2017-06-22 16:46:45

2021-02-23 15:18:27

程序員國企工程師

2022-06-06 15:44:24

大數據數據分析思維模式

2024-11-13 08:36:28

2018-12-29 10:37:05

HTTP緩存URL

2018-09-05 10:39:23

2014-09-05 16:58:52

程序員老程序員

2018-06-06 17:17:45

GitHub工程師代碼
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久亚洲视频网 | 日本色综合 | 日日夜夜免费精品视频 | 中文字幕亚洲精品在线观看 | 黄色毛片在线看 | 亚洲在线看 | 天天插天天操 | 国产精品99久久久久久大便 | 成人免费淫片aa视频免费 | 96av麻豆蜜桃一区二区 | 欧美在线 | 中文字幕免费视频 | 国产精品一区二区三区四区 | 成年人免费网站 | 亚洲精品丝袜日韩 | 成人性生交大片免费看中文带字幕 | 国产激情片在线观看 | 成人免费高清 | www.精品一区| 精品久久一 | 2022精品国偷自产免费观看 | 欧美久久久久久久久 | 国产日产久久高清欧美一区 | 综合久久一区 | 亚洲欧美一区二区在线观看 | 亚洲精品中文字幕中文字幕 | 日韩一区欧美一区 | 在线观看成人 | 国产亚洲高清视频 | 欧美8一10sex性hd| 日韩一级黄色片 | 久久久久精 | 夜夜骑天天干 | 尤物在线精品视频 | 一区在线观看 | 国产9999精品 | 国产蜜臀97一区二区三区 | www.久久| 天天爱av| 一区在线视频 | 伊人在线 |