iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 23
0
Modern Web

關於React,那些我不知道的系列 第 23

狀態管理的救星?! Recoil 來自遠方的狀態,如何處理Async State? (2)

  • 分享至 

  • xImage
  •  

希望獲取非同步狀態時,卻希望自定義元件流程時

狀態管理的救星?! Recoil 來自遠方的狀態,如何處理Async State?

原版 Demo (useRecoilValue)
Loadable版 Demo (useRecoilValueLoadable)

情境

在上一次我們提到了如何獲取 Async State ,提到我們可以透過 selector 使用 async function ,並在裡面對資料做處理。 但是元件流程上卻是被 <Suspense> 綁定了,如果我們想要多一點客製化的 loading state UI 跟 error state UI 的話,我們可以藉由 Loadable APIs 來達成。

Loadable APIs

  1. useRecoilValueLoadable
  2. useRecoilStateLoadable

並藉由其中的 Loadable的3個狀態 做切換元件,有哪3個狀態呢?分別是:

1.'hasValue'
2.'loading'
3.'hasError'

Recoil 提供這3種狀態給我們,接著我們就可以根據這些狀態渲染我們對應的元件。

詳情請看範例....
原版 Demo (useRecoilValue)
Loadable版 Demo (useRecoilValueLoadable)

範例

1.更改成 Loadable API

元件 <UserNameShowCase>

原本使用的 API 從 useRecoilValue 改為 useRecoilValueLoadable

  //  const userName = useRecoilValue(currentUserNameState);
  const userNameLoadable = useRecoilValueLoadable(currentUserNameState);

2.寫一組 switch case,抽換原本單一元件成 成功、錯誤以及讀取的3種元件、狀態

元件 <UserNameShowCase>

原本直接回傳該 useName (Recoil state) 的元件,被換成一組 switch case , Loadable的3個狀態 被放在 userNameLoadable.state 當中,因此我們放入 switch 裡做條件判斷。

而再根據 switch 不同的 case 回傳對應的元件,原本的 useName (Recoil state) ,則被放入 userNameLoadable.contents 當中。

/*
  return (
    <div
      style={{
        height: 100,
        width: 100,
        backgroundColor: "pink",
        display: "flex",
        alignItems: "center",
        justifyContent: "center"
      }}
    >
      {userName}
    </div>
*/

  switch (userNameLoadable.state) {
    case "hasValue":
      return <Comp2 name={userNameLoadable.contents} />;
    case "loading":
      return <LoadingComp2 />;
    case "hasError":
      throw userNameLoadable.contents;
  }

3.同理修改 <CurrentUserInfo> 元件

  // const userName = useRecoilValue(currentUserNameState);
  const userNameLoadable = useRecoilValueLoadable(currentUserNameState);
  //   return <div>User name :{userName} </div>;
  switch (userNameLoadable.state) {
    case "hasValue":
      return <div>{userNameLoadable.contents}</div>;
    case "loading":
      return <LoadingComp1 />;
    case "hasError":
      throw userNameLoadable.contents;
    default:
  }

4. 移除 <Suspense fallback={<h1>loading......</h1>}>


上一篇
如何做一個 銀行/分行的選單 selectorFamily
下一篇
Recoil API 總結
系列文
關於React,那些我不知道的30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言