這個簡單的竅門能大大改善 React 開發體驗

王大冶發表於2024-11-07
  • React Hook 深入淺出
  • CSS技巧與案例詳解
  • vue2與vue3技巧合集
  • VueUse原始碼解讀

問題背景

作為一名 React 開發者,在 JSX 中編寫條件渲染時總會遇到一些煩惱。看看這些常見的程式碼:

{isVisible && (
  <>
    <Header />
    <Content />
  </>
)}

{
  isLoggedIn 
  ? <UserDashboard /> 
  : <LoginForm />
}

這種寫法雖然能用,但存在以下問題:

  • 大量的花括號和括號使程式碼難以閱讀
  • 巢狀條件時結構更加混亂
  • 程式碼不夠優雅直觀

從開發的角度來看,這似乎不是一個主要的痛點,但它更像是一種沉悶而持久的煩惱😖。它常常讓我感到沮喪,尤其是當程式碼結構變得複雜時--三元運算讓我的程式碼看起來很難看,也更難理解🤯。

靈感來源:Solid.js 的優雅方案

從 Solid.js 框架獲得靈感,可以建立一個 Show 元件來最佳化條件渲染的寫法:

// Show 元件型別定義
interface ShowProps<T> {
  when: T | undefined | null | false;
  fallback?: React.ReactNode;
  children: React.ReactNode | ((item: T) => React.ReactNode);
}

實現方案

建立一個簡單但強大的 Show 元件:

function Show({ when, fallback = null, children }) {
  return when ? children : fallback;
}

使用示例

1. 基礎條件渲染

// ❌ 舊寫法
{isLoading && <Spinner />}

// ✅ 新寫法
<Show when={isLoading}>
  <Spinner />
</Show>

2. 條件分支渲染

// ❌ 舊寫法
{isAdmin 
  ? <AdminPanel /> 
  : <UserPanel />
}

// ✅ 新寫法
<Show 
  when={isAdmin}
  fallback={<UserPanel />}
>
  <AdminPanel />
</Show>

3. 複雜條件渲染

// ❌ 舊寫法
{isCommentsEnabled && (
  <>
    <CommentsHeader />
    {comments.map(comment => (
      <CommentItem key={comment.id} {...comment} />
    ))}
    {isLoggedIn && <CommentForm />}
  </>
)}

// ✅ 新寫法
<Show when={isCommentsEnabled}>
  <CommentsHeader />
  {comments.map(comment => (
    <CommentItem key={comment.id} {...comment} />
  ))}
  <Show when={isLoggedIn}>
    <CommentForm />
  </Show>
</Show>

4. 帶資料處理的條件渲染

// ❌ 舊寫法
{user && (
  <div>
    Welcome, {user.name}!
    {user.isAdmin && <AdminBadge />}
  </div>
)}

// ✅ 新寫法
<Show when={user}>
  {(userData) => (
    <div>
      Welcome, {userData.name}!
      <Show when={userData.isAdmin}>
        <AdminBadge />
      </Show>
    </div>
  )}
</Show>

擴充套件功能

還可以新增一些實用的功能:

// 支援非同步資料
const AsyncShow = ({ when, fallback, children }) => {
  const [isLoading, setIsLoading] = useState(true);
  const [data, setData] = useState(null);

  useEffect(() => {
    Promise.resolve(when).then(result => {
      setData(result);
      setIsLoading(false);
    });
  }, [when]);

  if (isLoading) return fallback;
  return data ? children : null;
};

// 使用示例
<AsyncShow 
  when={fetchUserData()} 
  fallback={<Loading />}
>
  {user => <UserProfile data={user} />}
</AsyncShow>

這個簡單的元件不僅能讓程式碼更加清晰易讀,還能提升開發效率。有時候最簡單的改進反而能帶來最大的收益!🎉

本文 GitHub https://github.com/qq449245884/xiaozhi 已收錄,有一線大廠面試完整考點、資料以及我的系列文章。

相關文章