自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

React19 她來了,她來了,他帶著禮物走來了

開發(fā) 前端
xdm,5.1玩的還可以嗎?既然已經(jīng)玩夠了,那么我們又得切換到上班模式。其實這篇文章是5.1之前開始寫的,為了讓大家能夠有一個輕松的假期,索性就沒在節(jié)內(nèi)發(fā)送。今天我們來聊聊前端的內(nèi)容。

前言

xdm,5.1玩的還可以嗎?既然已經(jīng)玩夠了,那么我們又得切換到上班模式。其實這篇文章是5.1之前開始寫的,為了讓大家能夠有一個輕松的假期,索性就沒在節(jié)內(nèi)發(fā)送。今天我們來聊聊前端的內(nèi)容。

React19她來了,她來了,她帶著??走來了。時隔2年多,React終于有了新版本了。你可知道,我們這兩年是如何過來的嗎?!

就在2024/04/25,我們可以通過npm install react@beta在本地安裝React19了。

圖片圖片

在React19沒發(fā)布之前,從各種小道消息中知曉了React在新版本中新增了很多特性,并且優(yōu)化了編譯流程。因為,本著沒有調(diào)查就沒有發(fā)言權(quán)的態(tài)度,我就遲遲沒有下筆。

既然,React19我們可以唾手可得了,那高低需要研究一波。

下面,我們就來看看她到底給我?guī)砹松叮?/p>

好了,天不早了,干點正事哇。

我們能所學(xué)到的知識點

  1. React v19 的新特性概覽
  2. React 編譯器
  3. 服務(wù)器組件(RSC)
  4. 動作(Action)
  5. Web Components
  6. 文檔元數(shù)據(jù)
  7. 資源加載
  8. 新的 React Hooks

1. React v19 的新特性概覽

  • React 編譯器:React 實現(xiàn)了一個新的編譯器。目前,Instagram 已經(jīng)在利用這項技術(shù)了。
  • 服務(wù)器組件(RSC):經(jīng)過多年的開發(fā),React 引入了服務(wù)器組件,而不是需要借助Next.js
  • 動作(Action):動作也將徹底改變我們與 DOM 元素的交互方式。
  • 文檔元數(shù)據(jù):這是另一個備受期待的改進(jìn),讓我們能夠用更少的代碼實現(xiàn)更多功能。
  • 資源加載:這將使資源在后臺加載,從而提高應(yīng)用程序的加載速度和用戶體驗。
  • Web Components:React 代碼現(xiàn)在可以讓我們集成 Web Components。
  • 增強(qiáng)的 hooks:引入了很多令人興奮的新 hooks,將徹底改變我們的編碼體驗。

下面我們就來一一探索其中的奧秘。

2. React 編譯器

其實React 編譯器就是之前早在React 2021年開發(fā)者大會上提出的React Forget,只不過最近才將其改為React 編譯器。

React 編譯器是一個「自動記憶編譯器」,可以自動執(zhí)行應(yīng)用程序中的所有記憶操作。

React 編譯器 的核心幾乎與 Babel 完全解耦,編譯器內(nèi)核其實就是「舊的 AST 輸入,新的 AST 輸出」。在后臺,編譯器使用自定義代碼表示和轉(zhuǎn)換管道來執(zhí)行語義分析。

React19之前的版本,當(dāng)狀態(tài)發(fā)生變化時,React有時會重新渲染不相干的部分。從React的早期開始,我們針對此類情況的解決方案一直是「手動記憶化」。在之前的API中,這意味著應(yīng)用useMemo、useCallback和memo API來手動調(diào)整React在狀態(tài)變化時重新渲染的部分。但手動記憶化只是一種「權(quán)宜之計」,它會使代碼變得復(fù)雜,容易出錯,并需要額外的工作來保持更新。React 團(tuán)隊意識到手動優(yōu)化很繁瑣,并且使用者對這種方式「怨聲載道」。

因此,React 團(tuán)隊創(chuàng)建了React 編譯器。React 編譯器現(xiàn)在將管理這些重新渲染。React 將「自行決定何時以及如何改變狀態(tài)并更新 UI」。

有了這個功能,我們不再需要手動處理這個問題。這也意味著讓人詬病的 useMemo()、useCallback() 和 memo要被歷史的車輪無情的碾壓。

React19 !=React 編譯器

圖片圖片

由于React 編譯器還未開源,所以我們無法得知其內(nèi)部實現(xiàn)細(xì)節(jié),不過我們可以從以往的動態(tài)中窺探一下。下面是一些與其相關(guān)的資料和視頻。

  • React 編譯器_youtube地址[1]
  • React Forget的基本介紹[2]

3. 服務(wù)器組件(RSC)

其實,在2023年,我們就注意到RSC,并且寫了幾篇文章。

圖片圖片

對應(yīng)的文章鏈接如下

  1. React Server Components手把手教學(xué)
  2. 用Rust搭建React Server Components 的Web服務(wù)器

服務(wù)器組件的想法已經(jīng)流傳了多年,Next.js 是第一個在生產(chǎn)環(huán)境中實現(xiàn)它們的。從 Next.js 13 開始,「默認(rèn)情況下所有組件都是服務(wù)器組件」。要使組件在客戶端運(yùn)行,我們需要使用'use client'指令。

在 React 19 中,服務(wù)器組件將直接集成到 React 中,帶來了一系列優(yōu)勢:

  1. 數(shù)據(jù)獲取: 服務(wù)器組件允許我們將數(shù)據(jù)獲取移至服務(wù)器端,更接近數(shù)據(jù)源。這可以通過減少獲取渲染所需數(shù)據(jù)的時間和客戶端需要發(fā)出的請求數(shù)量來提高性能。
  2. 安全性: 服務(wù)器組件允許我們將「敏感數(shù)據(jù)和邏輯」保留在服務(wù)器端,而無需暴露給客戶端的風(fēng)險。
  3. 緩存: 由于在服務(wù)器端渲染,結(jié)果可以被緩存并在后續(xù)請求和跨用戶時重復(fù)使用。這可以通過減少每個請求所需的渲染和數(shù)據(jù)獲取量來提高性能并降低成本。
  4. 性能: 服務(wù)器組件為我們提供了額外的工具來從基線優(yōu)化性能。例如,如果我們從一個完全由客戶端組件組成的應(yīng)用程序開始,將非交互式UI部分移至服務(wù)器組件可以減少所需的客戶端JavaScript。這對于網(wǎng)絡(luò)較慢或設(shè)備性能較低的用戶來說是有益的,因為瀏覽器需要下載、解析和執(zhí)行的客戶端JavaScript更少。
  5. 初始頁面加載和首次內(nèi)容渲染(FCP): 在服務(wù)器端,我們可以生成HTML,允許用戶立即查看頁面,而無需等待客戶端下載、解析和執(zhí)行渲染頁面所需的JavaScript。
  6. SEO:RSC通過為網(wǎng)絡(luò)爬蟲提供更可訪問的內(nèi)容來增強(qiáng)搜索引擎優(yōu)化。
  7. 流式傳輸: 服務(wù)器組件允許我們將渲染工作分割成塊,并在它們準(zhǔn)備就緒時將其流式傳輸?shù)娇蛻舳恕_@允許用戶在不必等待整個頁面在服務(wù)器端渲染完成的情況下,更早地看到頁面的某些部分。

如何使用服務(wù)器組件

默認(rèn)情況下,React 中的所有組件都是客戶端組件。只有使用 'use server' 時,組件才是服務(wù)器組件。

我們只需要將 'use server' 添加為組件的第一行即可。這將使組件成為服務(wù)器組件。它不會在客戶端運(yùn)行,只會在服務(wù)器端運(yùn)行。

'use server';

export default async function requestUsername(formData) {
  const username = formData.get('username');
  if (canRequest(username)) {
    // ...
    return 'successful';
  }
  return 'failed';
}

4. 動作(Action)

在 React19中,另一個令人興奮的新增功能將是Action。這將是我們處理表單的重大變革。

何為Action

使用異步轉(zhuǎn)換的函數(shù)被稱為Action(動作)。Action自動管理數(shù)據(jù)的提交:

  1. Pending狀態(tài):Action提供了一個state

請求開始時,代表對應(yīng)的狀態(tài)- pending狀態(tài)

請求結(jié)束時,狀態(tài)自動重置

  1. Optimistic更新:Action支持新的useOptimistic hook,因此我們可以在請求提交時向用戶顯示即時反饋。
  2. 錯誤處理:Action提供錯誤處理,因此我們可以在請求失敗時顯示Error Boundary,并自動恢復(fù)Optimistic更新為其原始值。
  3. 增強(qiáng)表單操作:<form>元素支持將函數(shù)傳遞給action和formAction props。
  • 傳遞給action props的函數(shù)默認(rèn)使用Action機(jī)制,并在提交后自動重置表單

Action將允許我們將action與<form/>標(biāo)簽 集成。簡單來說,我們將能夠用action替換 onSubmit 事件。

在使用Action之前

在下面的代碼片段中,我們將利用 onSubmit事件,在表單提交時觸發(fā)搜索操作。

<form notallow={search}>
  <input name="query" />
  <button type="submit">查詢</button>
</form>

使用Action后

隨著服務(wù)器組件的引入,  Action可以在服務(wù)器端執(zhí)行。在我們的 JSX 中,我們可以刪除 <form/> 的 onSubmit 事件,并使用 action 屬性。action 屬性的值將是一個「提交數(shù)據(jù)的方法」,可以在客戶端或服務(wù)器端提交數(shù)據(jù)。

我們可以使用Action執(zhí)行同步和異步操作,簡化數(shù)據(jù)提交管理和狀態(tài)更新。目標(biāo)是使處理表單和數(shù)據(jù)更加容易。

"use server"

const submitData = async (userData) => {
    const newUser = {
        username: userData.get('username'),
        email: userData.get('email')
    }
    console.log(newUser)
}
const Form = () => {
    return <form action={submitData}>
        <div>
            <label>用戶名</label>
            <input type="text" name='username'/>
        </div>
        <div>
            <label>郵箱</label>
            <input type="text" name="email" />
        </div>
        <button type='submit'>提交</button>
    </form>
}

export default Form;

在上面的代碼中,submitData 是服務(wù)器組件中的Action。form 是一個客戶端組件,它使用 submitData 作為Action。submitData 將在服務(wù)器上執(zhí)行。

5. Web Components

如果大家公司技術(shù)方案不是單一的。例如,公司有很多項目,并且項目中使用了不同的技術(shù)框架React/Vue等。然而,此時有一個功能需要多項目多框架使用,那么我們可以考慮一下,將此功能用Web Components實現(xiàn)。

Web Components

Web 組件允許我們使用原生 HTML、CSS 和 JavaScript 創(chuàng)建自定義組件,無縫地將它們整合到我們的 Web 應(yīng)用程序中,就像使用HTML 標(biāo)簽一樣。

三要素

  1. Custom elements(自定義元素):一組 JavaScript API,允許我們定義 custom elements 及其行為,然后可以在我們的用戶界面中按照需要使用它們。

通過 class A extends HTMLElement {} 定義組件,

通過 window.customElements.define('a-b', A) 掛載已定義組件。

  1. Shadow DOM(影子 DOM ):一組 JavaScript API,用于將封裝的“影子” DOM 樹附加到元素(「與主文檔 DOM 分開呈現(xiàn)」)并控制其關(guān)聯(lián)的功能。
  • 通過這種方式,我們可以「保持元素的功能私有」,這樣它們就可以被腳本化和樣式化,而不用擔(dān)心與文檔的其他部分發(fā)生沖突。

  • 使用 const shadow = this.attachShadow({mode : 'open'}) 在 WebComponents 中開啟。

  1. HTML templates(HTML 模板)slot :template 可以簡化生成 dom 元素的操作,不再需要 createElement 每一個節(jié)點。

雖然 WebComponents 有三個要素,但卻不是缺一不可的,WebComponents

  • 借助 shadow dom  來實現(xiàn)「樣式隔離」,
  • 借助 templates 來「簡化標(biāo)簽」的操作。

內(nèi)部生命周期函數(shù)(4個)

  1. connectedCallback: 當(dāng) WebComponents 「第一次」被掛在到 dom 上是觸發(fā)的鉤子,并且只會觸發(fā)一次。

類似  React 中的 useEffect(() => {}, []),componentDidMount。

  1. disconnectedCallback: 當(dāng)自定義元素與文檔 DOM 「斷開連接」時被調(diào)用。
  2. adoptedCallback: 當(dāng)自定義元素被「移動」到新文檔時被調(diào)用。
  3. attributeChangedCallback: 當(dāng)自定義元素的被監(jiān)聽屬性變化時被調(diào)用。

如果不想用原生寫,那么我們可以選擇一些成熟的框架,例如Lit[3]

圖片圖片

React19 兼容 Web Components

在React19之前,在 React 中集成 Web Components并不直接。通常,我們需要將 Web Components轉(zhuǎn)換為 React 組件,或者安裝額外的包并編寫額外的代碼來使 Web Components與 React 協(xié)同工作。

React 19 將幫助我們更輕松地將 Web Components整合到我們的 React 代碼中。如果我們遇到一個非常有用的 Web Components,我們可以無縫地將其整合到 React 項目中,而不需要將其轉(zhuǎn)換為 React 代碼。

這簡化了開發(fā)流程,并允許我們在 React 應(yīng)用程序中利用現(xiàn)有 Web Components的廣泛生態(tài)系統(tǒng)。

6. 文檔元數(shù)據(jù)

TKD

在做SEO時,我們需要在<meta>中處理title/keywords/description的信息。

  1. title的權(quán)重最高,利用title提高頁面權(quán)重
  2. keywords相對權(quán)重較低,作為頁面的輔助關(guān)鍵詞搜索
  3. description的描述一般會直接顯示在搜索結(jié)果的介紹中

當(dāng)然處理SEO不僅僅這點方式,還有在項目中新增Sitemap.xml還有使用rel=canonical的連接,想了解更多的方式,可以參考SEO教程[4]

處理SEO

經(jīng)常借助編寫自定義代碼或使用像 react-helmet[5] 這樣的包來處理路由更改并相應(yīng)地更新元數(shù)據(jù)。這個過程可能會重復(fù),而且容易出錯,特別是在處理像 meta 標(biāo)簽這樣對 SEO 敏感的元素時。

React19之前的SEO

import React, { useEffect } from 'react';

const HeadDocument = ({ title }) => {
  useEffect(() => {
    document.title = title;

  const metaDescriptionTag = document.querySelector('meta[name="description"]');
    if (metaDescriptionTag) {
    metaDescriptionTag.setAttribute('content', '前端柒八九');
    }
  }, [title]);

  return null;
};

export default HeadDocument;

在上面的代碼中,我們有一個名為 HeadDocument 的組件,基于props 更新title和 meta 標(biāo)簽。我們在 useEffect 鉤子中更新這些內(nèi)容。我們還使用 JavaScript 來更新標(biāo)題和 meta 標(biāo)簽。這個組件將在路由更改時更新。

React19的SEO

使用 React19后,我們可以直接在 React 組件中使用<title>和 <meta> 標(biāo)簽:

Const HomePage = () => {
  return (
    <>
      <title>React19</title>
      <meta name="description" content="前端柒八九" />
      // 頁面內(nèi)容
    </>
  );
}

當(dāng)然,我們可以基于props來更新title/meta中的對應(yīng)信息。

7.資源加載

在 React 中,我們需要特別關(guān)心應(yīng)用程序的加載體驗和性能,特別是圖片和其他資源文件。

通常,視圖會首先在瀏覽器中渲染,然后是樣式表、字體和圖片。這可能會導(dǎo)致FOIT或者FOUT。

我們在瀏覽器之性能指標(biāo)-CLS中有過介紹,這里我們就拿來主義了。

FOIT/FOUT

FOIT和FOUT是與Web字體加載相關(guān)的術(shù)語。

FOIT代表"Flash of Invisible Text",意為「不可見文本的閃爍」。

當(dāng)使用Web字體時,瀏覽器在下載字體文件時,會顯示一段時間的空白文本,直到字體文件完全加載完成。這段時間內(nèi),用戶可能會看到頁面上出現(xiàn)了空白文本,然后突然閃現(xiàn)出字體樣式。這種體驗被稱為FOIT。

FOUT代表"Flash of Unstyled Text",意為「未樣式化文本的閃爍」。

與FOIT類似,當(dāng)使用Web字體時,瀏覽器可能會「先顯示系統(tǒng)默認(rèn)字體」,然后在字體文件加載完成后,突然將文本樣式化為所需的Web字體。這種體驗被稱為FOUT。

FOIT和FOUT都是由于Web字體加載的延遲而導(dǎo)致的不佳用戶體驗。用戶可能會看到文本內(nèi)容在加載過程中發(fā)生閃爍或樣式變化,給頁面的整體穩(wěn)定性和一致性帶來了困擾。為了解決FOIT和FOUT問題,可以使用CSS屬性,如font-display,來控制字體加載和顯示的方式,以平滑地呈現(xiàn)文本內(nèi)容,提高用戶體驗。

或者我們可以「添加自定義代碼來檢測這些資源何時準(zhǔn)備好」,確保視圖只在所有內(nèi)容加載完畢后顯示。

在 React 19 中,當(dāng)用戶瀏覽當(dāng)前頁面時,圖片和其他文件將「在后臺加載」。

這個改進(jìn)應(yīng)該有助于提高頁面加載速度并減少等待時間。

此外,React 還引入了用于資源加載的生命周期 Suspense,包括script、樣式表和字體。這個特性使 React 能夠確定內(nèi)容何時準(zhǔn)備好顯示,消除了任何FOUT的閃爍現(xiàn)象。

還有新的資源加載 API,比如 preload 和 preinit,可以提供更大的控制力,確定何時加載和初始化資源。

通過允許資源在后臺異步加載,React 19減少了等待時間,確保用戶可以在不間斷的情況下與內(nèi)容進(jìn)行交互。

8. 新的 React Hooks

自從React16.8引入Hook機(jī)制以來,React的開發(fā)模式就發(fā)生了翻天覆地的變化。她提供的各種內(nèi)置Hook大大提高了我們開發(fā)組件的效率。并且,我們還可以通過封裝各種自定義Hook來處理共有邏輯。也就是說,Hook在React中有舉足輕重的地位。Hook已經(jīng)成為了開發(fā)React的主流編程模式。

雖然,Hook為我們帶來了很多的便利,但是有些Hook的使用卻需要各種限制,稍不留神就會讓頁面陷入萬劫不復(fù)的地步。所以React19對一些我們平時用起來不咋得心應(yīng)手的Hook做了一次升級。

在 React 19 中,我們使用 useMemo、forwardRef、useEffect 和 useContext 的方式將會改變。這主要是因為將引入一個新的 hook,即 use。

useMemo()

在 React19 之后,我們不再需要使用 useMemo() hook,因為 React編譯器 將會自動進(jìn)行記憶化。

之前的寫法

import React, { useState, useMemo } from 'react';

function ExampleComponent() {
  const [inputValue, setInputValue] = useState('');

  // 記住輸入框是否為空的檢查結(jié)果
  const isInputEmpty = useMemo(() => {
    console.log('檢測輸入框是否為空');
    return inputValue.trim() === '';
  }, [inputValue]);

  return (
    <div>
      <input
        type="text"
        value={inputValue}
        onChange={(e) => setInputValue(e.target.value)}
      />
      <p>{isInputEmpty ? 'Input 為空' : 'Input有值'}</p>
    </div>
  );
}

export default ExampleComponent;

之后的寫法

在下面的例子中,我們可以看到在 React19 之后,我們不再需要自己來做記憶化,React19 將會在后臺自動完成。

import React, { useState } from 'react';

function ExampleComponent() {
  const [inputValue, setInputValue] = useState('');

  const isInputEmpty = () => {
    console.log('檢測輸入框是否為空');
    return inputValue.trim() === '';
  });

  return (
    <div>
      <input
        type="text"
        value={inputValue}
        onChange={(e) => setInputValue(e.target.value)}
      />
      <p>{isInputEmpty ? 'Input 為空' : 'Input有值'}</p>
    </div>
  );
}

export default ExampleComponent;

forwardRef()

ref 現(xiàn)在將作為props傳遞而不是使用 forwardRef() hook。

這將簡化代碼。因此,在 React19 之后,我們不需要使用 forwardRef()。

之前的寫法

import React, { forwardRef } from 'react';

const ExampleButton = forwardRef((props, ref) => (
  <button ref={ref}>
    {props.children}
  </button>
));

之后的寫法

ref 可以作為屬性傳遞。不再需要 forwardRef()。

import React from 'react';

const ExampleButton = ({ ref, children }) => (
  <button ref={ref}>
    {children}
  </button>
);

新的 use() hook

React19 將引入一個新的 hook,名為 use()。這個 hook 將簡化我們?nèi)绾问褂?nbsp;promises、async 代碼和 context。

語法

const value = use(resource);

示例1:接收async函數(shù)

下面的代碼是使用 use hook 進(jìn)行 fetch 請求的示例:

import { use } from "react";

const fetchUsers = async () => {
    const res = await fetch("遠(yuǎn)程地址");
    return res.json();
  };
  
const UsersItems = () => {
  const users = use(fetchUsers());

  return (
    <ul>
      {users.map((user) => (
        <div key={user.id} >
          <h2>{user.name}</h2>
          <p>{user.email}</p>
        </div>
      ))}
    </ul>
  );
}; 
export default UsersItems;

讓我們理解一下代碼:

  • fetchUsers進(jìn)行遠(yuǎn)程數(shù)據(jù)請求
  • 我們使用 use hook 執(zhí)行 fetchUsers,而不是使用 useEffect 或 useState hooks。
  • use hook 的返回值是 users,其中包含 GET 請求的響應(yīng)(users)。
  • 在return中,我們使用 users進(jìn)行對應(yīng)信息的渲染處理。

示例2:接收context對象

我們以后可以直接將context對象傳人到use()中,從而達(dá)到將context引入組件的目的。而不需要useContext()了。

使用createContext定義全局變量

這里我們定義

import { createContext, useState, use } from 'react';

const ThemeContext = createContext();

const ThemeProvider = ({ children }) => {
  const [theme, setTheme] = useState('light');

  const toggleTheme = () => {
    setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light'));
  };

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
};
在組件中使用use()獲取context信息
const Card = () => {
  // use Hook()
  const { theme, toggleTheme } = use(ThemeContext);

  return (
    // 基于theme/toggleTheme 渲染頁面或者執(zhí)行對應(yīng)的操作
  );
};

const Theme = () => {
  return (
    <ThemeProvider>
      <Card />
    </ThemeProvider>
  );
};

export default Theme

上面代碼中有幾點需要簡單解釋一下:

  • ThemeProvider 負(fù)責(zé)提供 context。
  • Card 是我們將消費(fèi) context 的組件。為此,我們將使用新的 hook use 來消費(fèi) context。

衍生一下

其實吧,use的內(nèi)部實現(xiàn)很簡單,就是基于傳人的對象類型進(jìn)行返回數(shù)據(jù)即可。

圖片圖片

針對,其內(nèi)部是如何實現(xiàn)的,我們后期會有專門的文章來介紹,這里就不在過多解釋了。

useFormStatus() hook

在 React19 中,我們還有新的 hooks 來處理表單狀態(tài)和數(shù)據(jù)。這將使處理表單更加流暢和簡單。將這些 hooks 與 Action結(jié)合使用將使處理表單和數(shù)據(jù)更加容易。

React19 中的這個新 hook 將幫助我們更好地控制你創(chuàng)建的表單。它將提供關(guān)于上次表單提交的狀態(tài)信息。

基礎(chǔ)語法

這是它的語法:

const { pending, data, method, action } = useFormStatus();

或者簡化的版本:

const { status } = useFormStatus()
  • pending:如果表單處于待處理狀態(tài),則為 true,否則為 false。
  • data:一個實現(xiàn)了 FormData 接口的對象,其中包含父 <form> 提交的數(shù)據(jù)。
  • method:HTTP 方法 – GET,或 POST。

默認(rèn)情況下將是 GET。

  • action:一個函數(shù)引用。

案例展示

useFormStatus是從react-dom庫中導(dǎo)出的

import { useFormStatus } from "react-dom";

function Submit() {
  const status = useFormStatus();
  return <button disabled={status.pending}>
        {status.pending ? '正在提交...' : '提交完成'}
    </button>;
}

// ==== 父組件 ==引入Submit ====

const formAction = async () => {
  // 模擬延遲 3 秒
  await new Promise((resolve) => setTimeout(resolve, 3000));
}

const FormStatus = () => {
  return (
    <form action={formAction}>
      <Submit />
    </form>
  );
};

export default FormStatus;

讓我們簡單解釋一下上面代碼:

  • Submit通過useFormStatus可以獲取此時from表單的提交狀態(tài),并基于一些狀態(tài)渲染一些輔助信息
  • formAction是執(zhí)行異步提交的處理

在上面的代碼中,當(dāng)表單提交時,從 useFormStatus hook 我們將獲得一個 pending 狀態(tài)。

  • 當(dāng) pending 為 true 時,UI 上會顯示 "正在提交..." 文本。
  • 一旦 pending 為 false,"正在提交..." 文本將被更改為 "提交完成"。

當(dāng)我們想要知道表單提交的狀態(tài)并相應(yīng)地顯示數(shù)據(jù)時,它會很有用。

useFormState() hook

React19 中的另一個新 hook 是 useFormState。它允許我們根據(jù)表單提交的結(jié)果來更新狀態(tài)。

語法

這是它的語法:

const [state, formAction] = 
      useFormState(
        fn, 
        initialState, 
        permalink?
      );
  • fn:表單提交或按鈕按下時要調(diào)用的函數(shù)。
  • initialState:我們希望狀態(tài)初始值是什么。它可以是任何可序列化的值。在首次調(diào)用操作后,此參數(shù)將被忽略。
  • permalink:這是可選的。一個 URL 或頁面鏈接,如果 fn 將在服務(wù)器上運(yùn)行,則頁面將重定向到 permalink。

這個 hook 將返回:

  • state:初始狀態(tài)將是我們傳遞給 initialState 的值。
  • formAction:一個將傳遞給表單操作的操作。此操作的返回值將在狀態(tài)中可用。

案例展示

import { useFormState} from 'react-dom';

const FormState = () => {
    const submitForm = (prevState, queryData) => {
        const name =  queryData.get("username");
        console.log(prevState); // 上一次的from 的state 
        if(name === '柒八九'){
            return {
                success: true,
                text: "前端開發(fā)者"
            }
        }
        else{
            return {
                success: false,
                text: "Error"
            }
        }
    }
    const [ message, formAction ] = useFormState(submitForm, null)
    return <form action={formAction}>
        <label>用戶名</label>
        <input type="text" name="username" />
        <button>提交</button>
        {message && <h1>{message.text}</h1>}
    </form>
}

export default FormState;

讓我們簡單解釋一下發(fā)生了啥

  • submitForm 是負(fù)責(zé)表單提交的方法。這是一個 Action。
  • 在 submitForm 中,我們正在檢查表單的值。

prevState:初始狀態(tài)將為 null,之后它將返回表單的 prevState。

queryData:用于獲取此次操作中from表單中對應(yīng)key的值

useOptimistic() hook

useOptimistic 也新發(fā)布的Hook,它允許我們在異步操作時顯示不同的狀態(tài)。

這個 hook 將幫助增強(qiáng)用戶體驗,并應(yīng)該導(dǎo)致更快的響應(yīng)。這對于需要與服務(wù)器交互的應(yīng)用程序非常有用。

語法

以下是 useOptimistic hook 的語法:

const [ optimisticX, addOptimisticX] = useOptimistic(state, updatefn)

例如,當(dāng)響應(yīng)正在返回時,我們可以顯示一個「optimistic狀態(tài)」,以便讓用戶獲得即時響應(yīng)。一旦服務(wù)器返回實際響應(yīng),optimistic狀態(tài)將被替換。

案例展示

import { useOptimistic, useState } from "react";

const Optimistic = () => {
  const [messages, setMessages] = useState([
    { text: "初始化信息", sending: false, key: 1 },
  ]);
  
  const [optimisticMessages, addOptimisticMessage] = useOptimistic(
    messages,
    (state, newMessage) => [
      ...state,
      {
        text: newMessage,
        sending: true,
      },
    ]
  );

  async function sendFormData(formData) {
    const sentMessage = await fakeDelayAction(formData.get("message"));
    setMessages((messages) => [...messages, { text: sentMessage }]);
  }

  async function fakeDelayAction(message) {
    await new Promise((res) => setTimeout(res, 1000));
    return message;
  }

  const submitData = async (userData) => {
    addOptimisticMessage(userData.get("username"));

    await sendFormData(userData);
  };

  return (
    <>
      {optimisticMessages.map((message, index) => (
        <div key={index}>
          {message.text}
          {!!message.sending && <small> (Sending...)</small>}
        </div>
      ))}
      <form action={submitData}>
        <h1>OptimisticState Hook</h1>
        <div>
          <label>Username</label>
          <input type="text" name="username" />
        </div>
        <button type="submit">Submit</button>
      </form>
    </>
  );
};

export default Optimistic;
  • fakeDelayAction 模擬一個異步操作。
  • submitData 是 action。這個方法負(fù)責(zé)表單提交。這也可以是 async 的。
  • sendFormData 負(fù)責(zé)將表單發(fā)送到 fakeDelayAction
  • 設(shè)置默認(rèn)狀態(tài)。messages 將用作 useOptimistic() 的輸入,并將返回 optimisticMessages。
const [messages, setMessages] = useState([{ text: "初始化信息", sending: false, key: 1 },]);

在 submitData 內(nèi)部,我們使用 addOptimisticMessage。這將添加表單數(shù)據(jù),以便在 optimisticMessage 中可用。我們將使用此數(shù)據(jù)在 UI 中顯示消息:

{optimisticMessages.map((message, index) => (
        <div key={index}>
          {message.text}
          {!!message.sending && <small> (Sending...)</small>}
        </div>
      ))}

其實,我們以后在處理類似Form表單狀態(tài)時,可以配合Action/useOptimistic/useFormState/useFormState進(jìn)行狀態(tài)的各種流轉(zhuǎn)處理。

圖片圖片


Reference

[1]React 編譯器_youtube地址:https://youtu.be/kjOacmVsLSE?si=dqCjg0_9x2hOB8BF

[2]React Forget的基本介紹:https://dev.to/usulpro/how-react-forget-will-make-react-usememo-and-usecallback-hooks-absolutely-redundant-4l68

[3]Lit:https://lit.dev/

[4]SEO教程:https://moz.com/beginners-guide-to-seo

[5]react-helmet:https://www.npmjs.com/package/react-helmet

責(zé)任編輯:武曉燕 來源: 前端柒八九
相關(guān)推薦

2024-04-28 09:01:06

React 19更新前端

2024-04-03 08:47:58

React服務(wù)端組件Actions

2019-11-06 16:33:29

Ignite微軟技術(shù)

2020-07-22 08:58:56

C++特性函數(shù)

2021-10-22 15:45:32

開發(fā)技能React

2022-09-21 18:41:15

英偉達(dá)顯卡

2021-04-16 16:21:02

鴻蒙HarmonyOS應(yīng)用開發(fā)

2025-01-15 10:02:09

APIVueDOM

2024-12-06 08:00:51

2010-02-03 13:25:34

云計算

2022-11-29 07:48:16

2024-11-25 16:41:20

2021-06-16 06:05:25

React18React

2021-11-16 14:21:02

React 開發(fā) Beta

2021-01-28 16:58:12

數(shù)字貨幣加密貨幣區(qū)塊鏈

2015-03-05 09:26:28

網(wǎng)絡(luò)中立命名數(shù)據(jù)網(wǎng)絡(luò)FDD

2014-06-23 09:04:56

Docker

2015-12-29 13:32:41

2014-12-08 09:55:33

Android 5.0Google

2020-10-09 08:38:14

Python 3.9Python開發(fā)
點贊
收藏

51CTO技術(shù)棧公眾號