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

React 中,最優雅的異步請求解決方案:use + Suspense

開發 前端
這篇文章繼續給大家分享在 React 19 中使用 use + Suspense 來處理異步請求為什么是目前我見過的更優雅的解決方案。

關于 React 19,我應該算是國內最早一個使用 React 19 的開發者。和許多還在觀望中的朋友不一樣,我已經深度使用 React 19 開發了幾個項目了,

?

當然,他的正式版還沒有發布。不過 RC 版更新非常頻繁,基本上兩三天就會發一個版本

雖然有部分項目沒有把 React 升級到 19 這個版本,但是我也將 React 19 中提到的開發思維抽離了出來,在低版本中使用。

這篇文章繼續給大家分享在 React 19 中使用 use + Suspense 來處理異步請求為什么是目前我見過的更優雅的解決方案。

一、傳統方案

解決異步請求的方案中,我們要處理至少兩個最基本的邏輯。

  • 正常的數據展示。
  • 數據加載的 UI 狀態。

在 react 傳統的方案中,我們將數據和 Loading 定義在不同的 state 中,然后通過判斷 Loading 狀態的變化,來識別應該返回什么樣的 UI 結果,然后借助 useEffect 來請求接口。

代碼大概如下所示:

很明顯,每個頁面都這樣干的話,會比較繁瑣。因此,我們通常會通過自定義 hook 的方式封裝請求邏輯,從而簡化每個頁面的代碼。

function useFetch() {
  const [content, update] = useState({value: ''})
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    api().then(res => {
      setLoading(false)
      update(res)
    })
  }, [])

  return {content, loading}
}

這樣,頁面代碼就變成了如下更簡潔的形式。

function Index2() {
  const {content, loading} =  useFetch()

  if (loading) {
    return <Skeleton />
  }

  return (
    <Message message={content.value} />
  )
}

?

大家常用的 ahooks,useQuery 等,都是這個封裝思路。

在 UI 層面,我們還可以做一層封裝,把 Loading 封裝到 UI 組件邏輯中去。常見的使用方式可以是這樣。

function Index2() {
  const {content, loading} =  useFetch()

  return (
    <Message 
      message={content.value} 
      loading={loading} 
    />
  )
}

也可以參考 antd 中,Spin 的使用方式。

function Index2() {
  const {content, loading} =  useFetch()

  return (
    <Spin tip="Loading...">
      <Message message={content.value} />
    </Spin>
  )
}

通過這樣的兩步優化讓我們的頁面代碼變得非常簡潔。這也是我在之前的版本中,使用最多的方式,開發效率也非常高。

剛開始使用這種方式時,我也非常驚訝,原來異步請求的邏輯處理可以整理得這么簡潔,這么得體。但是隨著使用經驗的增加,也處理了更多的場景,幾乎絕大多數場景都能夠平滑的應對,但是我依然發現這種方式存在一些小小的痛點。

當我們在思考如何封裝這個 useFetch 時,首先會考慮清楚在眾多場景之下,有哪些東西是變化量。變化的內容我們將其設計為參數傳入。

function useFetch(params) {
  ...
}

常見的變化量包括:

  • 入參不同
  • 請求方式不同
  • 返回類型不同
  • 部分場景需要初始的默認值
  • 部分場景的接口并不需要立即請求
  • 返回結果可能需要二次處理才能正常使用
  • 參數變化之后的處理邏輯不同
  • ...

當不同的東西開始變得越來越多,我逐漸發現一個事情,那就是優雅正在消失...

?

當然最終我肯定是有對應的成套架構解決方案,但是這對于普通開發者來說會變得有點難度,需要更豐富的經驗來支撐才能應對各種不同的場景。

二、React 19 的新方案

讓我感覺到比較驚喜的是,React 19 提出了一個新的方式,讓我們應對這些復雜場景變得更加簡單。那就是 use + promise + Suspense。

首先來簡單學習一下 React19 中的做法。

首先,我們會把數據存儲在 promise 中。然后將 promise 定義為 state。

const _api3 = (params) => {
  return new Promise(resolve => {
    resolve({ value: 'React does not preserve any state for renders that got suspended before they were able to mount for the first time. When the component has loaded, React will retry rendering the suspended tree from scratch.' })
  })
}
const [promise, setPromise] = useState(_api3)

如果有默認參數需要傳入,只需要在執行 _api3 時傳入參數即可。

const promise = useState(() => _api3({value: 10}))

如果我們在點擊時,需要修改參數并且重新請求接口,那么我們的做法也很簡單,一樣是重新執行 _api3 即可。

function clickHandler() {
  _api({value: 20})
}

由于觸發 UI 更新必須要借助 state 的變化,因此,我們將每次 _api3 執行返回的 promise 存儲在 sueState 中,點擊時,_api3 的執行結果必定是新的 promise 對象,因此,代碼更改為如下,即可觸發 UI 的更新。

function clickHandler() {
  setPromise(_api({value: 20}))
}

然后,我們將 promise 傳入到具體的 UI 組件中去,并使用 Suspense 包裹起來。

export default function Index() {
  const [promise, setPromise] = useState(_api3)
  return (
    <Suspense fallback={<Skeleton />}>
      <Message promise={promise} />
    </Suspense>
  )
}

然后在 UI 組件內部,使用 use 獲取 promise 中的數據即可。

const Message = (props) => {
  const content = use(props.promise)
  return (
    <div className='flex border border-blue-100 p-4 rounded-md shadow'>
      ...
    </div>
  )
}

此時我們發現,在這套解決方案之下,參數的多變性處理起來就變得非常容易。我們可以直接控制參數是否變化,也可以直接控制接口是否需要重新請求。

我們只需要按照需求,在響應實踐中執行對應的邏輯,就可以了。而不需要像上面那種方案一樣,還要額外封裝,否則代碼就會變得很亂。

認真體會這段代碼的優雅性。

function clickHandler() {
  setPromise(_api({value: 20}))
}

我們可以非常自由的在不同的場景處理參數。例如,有的地方可能需要緩存上一次的參數,但是有的地方不需要。那么,需要緩存的場景,我們隨便單獨緩存即可。

也不用受限于參數的變化是否會引發接口的重新請求。這里參數的變化與接口的執行被解耦開,直接由我們開發時控制

三、總結

很顯然,react19 中提到的解決異步邏輯的方案,是目前為止,我見到過的最優雅的方案。這種方案不需要我們再進一步二次封裝,就能夠輕松應對各種復雜的場景。這必將成為未來開發的主流方案。

現在 react19 正式版本還沒有發布,加上熱衷于使用 react19 的博主只有我一個,因此這種方案目前只是在很小的范圍內被使用,成為主流可能還需要一點時間的傳播和學習。

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

2009-10-27 15:35:08

2010-08-05 13:20:41

Flex最優布局

2009-10-21 14:00:25

綜合布線解決方案

2009-10-14 13:54:49

寬帶布線系統

2017-08-02 14:17:08

前端asyncawait

2023-11-03 14:32:38

2013-02-22 10:46:12

華為解決方案IDEAL

2024-10-14 08:29:14

異步編程任務

2009-12-16 13:39:27

Ruby元編程

2022-02-09 07:25:34

SuspenseReact項目

2022-10-17 17:45:02

2023-11-17 09:38:21

2022-12-27 11:06:35

海量接口并發

2024-10-08 10:10:00

削峰高并發流量

2013-07-01 09:46:30

移動虛擬化BYOD

2021-06-28 08:10:59

JavaScript異步編程

2011-10-28 17:45:30

數據中心極性管理

2022-03-01 09:31:06

JWTSession跨域

2021-02-23 10:34:51

Java 編程開發

2024-09-18 00:15:58

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 搞av.com | 毛片av免费在线观看 | 韩日av在线 | 美女久久久久久久 | 国产乱码精品一区二区三区中文 | 久久久精品网站 | 久久这里只有精品首页 | 国产清纯白嫩初高生视频在线观看 | 男女下面一进一出网站 | 久久99精品国产自在现线小黄鸭 | 亚洲欧美日韩精品久久亚洲区 | 黄色免费在线观看 | 久久久国| 日日干夜夜操天天操 | av一区二区三区四区 | 亚洲成人自拍 | 羞羞的视频免费在线观看 | 久久一本 | 成人免费视频网址 | 精品欧美一区二区在线观看视频 | 欧美天天视频 | 免费观看a级毛片在线播放 黄网站免费入口 | 欧美一级艳情片免费观看 | 北条麻妃av一区二区三区 | 黑人巨大精品欧美一区二区一视频 | 中文字幕精品一区 | 一区二区免费高清视频 | 欧美精品tv | 成人在线观看免费 | 99综合网 | 玖玖在线精品 | 中文字幕日韩欧美一区二区三区 | 一区二区三区免费 | 成人福利在线视频 | 神马久久久久久久久久 | 日韩av.com | 91亚洲国产精品 | 九九精品影院 | 成人午夜视频在线观看 | 97伊人 | 亚洲三区在线观看 |