how-to-use-react

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

React の使い方

React 的使用方法

大本は次の資料で、masseater/typescript-template から作ったリポジトリ向けに読み替えてある。読み替えと原典が食い違うときは読み替えを採る。
主要依据以下资料,并已针对基于 masseater/typescript-template 创建的仓库进行调整。如果调整内容与原始资料不一致,则以调整后的内容为准。

置き分け

职责划分

やりたいこと使うもの使わないもの
画面の一時状態、フォームの値、ツリーをまたいで共有する値Effect Atom(
Atom.make
、
useAtom
、
useAtomValue
)
useState
、
useReducer
、
createContext
、
useContext
(
no-restricted-imports
が拒否する)
サーバーデータTanStack Query(
queryOptions
は FSD の
api
セグメント)
use(promise)
での取得、
useEffect
と
fetch
の組み合わせ、Atom にサーバー応答を載せる
ミューテーションの pending と errorTanStack Query の
useMutation
自前の pending フラグ、
useActionState
、
useFormStatus
順番が仕様のミューテーション同じ
scope.id
を持つ
useMutation
自前のキュー、ボタンを無効にして操作列を止める
楽観更新
useOptimistic
自前の巻き戻し状態
急がない更新・重い派生
useTransition
/
startTransition
/
useDeferredValue
タイマーデバウンス
ref関数の props
forwardRef
、文字列 ref
隠しても状態を残す
<Activity mode="hidden">
条件付きアンマウントで状態を捨てる
遷移のアニメーション
<ViewTransition>
Effect で最新の props を使う
useEffectEvent
。依存配列には入れない
その関数を依存配列に足して購読をやり直す
要实现的事情使用不使用
界面的临时状态、表单值、跨组件树共享的值Effect Atom(
Atom.make
、
useAtom
、
useAtomValue
)
useState
、
useReducer
、
createContext
、
useContext
(
no-restricted-imports
会拒绝)
服务端数据TanStack Query(
queryOptions
放在 FSD 的
api
segment 中)
使用
use(promise)
获取、使用
useEffect
与
fetch
组合、将服务端响应放入 Atom
Mutation 的 pending 和 errorTanStack Query 的
useMutation
自行维护的 pending 标志、
useActionState
、
useFormStatus
顺序有明确要求的 Mutation使用相同
scope.id
的
useMutation
自定义队列、禁用按钮并中断操作序列
乐观更新
useOptimistic
自行维护的回滚状态
不紧急的更新、高开销派生值
useTransition
/
startTransition
/
useDeferredValue
基于计时器的 debounce
ref函数形式的 props
forwardRef
、字符串 ref
隐藏后仍保留状态
<Activity mode="hidden">
通过条件卸载丢弃状态
过渡动画
<ViewTransition>
在 Effect 中使用最新的 props
useEffectEvent
。不要放入依赖数组
将该函数加入依赖数组并重新建立订阅

メモ化

记忆化

React Compiler が有効なリポジトリでは
useMemo
、
useCallback
、
memo
を書かない。 Compiler が無いリポジトリでは、
react-perf
のルールが props に渡す関数やオブジェクトの作り直しを指摘した箇所にだけ
useCallback
/
useMemo
を書く。それ以外は計測で遅いと分かってから足す。
在启用了 React Compiler 的仓库中,不编写
useMemo
、
useCallback
、
memo
。
在没有 Compiler 的仓库中,仅当
react-perf
规则指出传入 props 的函数或对象被重复创建时,才在这些位置编写
useCallback
/
useMemo
。除此之外,只有在测量确认性能缓慢后再添加。

コンポーネントを書くとき

编写组件时

  1. 派生値はレンダー中に計算する。Effect で props を state にコピーしない。
  2. Effect は React の外(DOM、計測、購読、ウィジェット)と同期するときだけ書き、後始末を返す(
    references/effects-and-data.md
    )。
  3. イベントで起きる画面の変化はトランジションが既定である(
    references/design-theory.md
    )。
  4. 操作列を止めないミューテーションは
    useOptimistic
    と組み合わせ、追加の操作を pending で無効にしない(
    references/action-queue.md
    )。
  5. 重い一覧は入力と
    useDeferredValue
    を分け、タイマーデバウンスを書かない(
    references/deferred-consistency.md
    )。
  6. <Activity>
    、
    <ViewTransition>
    、
    useEffectEvent
    の使いどころは
    references/concurrent-ux.md
    。
  7. props の形は
    references/component-apis.md
    、名前とファイルは
    references/naming.md
    。
  1. 派生值在渲染期间计算。不要在 Effect 中将 props 复制到 state 中。
  2. 仅当 Effect 需要与 React 外部的系统(DOM、测量、订阅、widget)同步时才编写,并返回清理函数(
    references/effects-and-data.md
    )。
  3. 由事件引起的界面变化默认使用 Transition(
    references/design-theory.md
    )。
  4. 不中断操作序列的 Mutation 应与
    useOptimistic
    结合使用,不要因 pending 而禁用后续操作(
    references/action-queue.md
    )。
  5. 对于开销较大的列表,将输入与
    useDeferredValue
    分离,不要编写基于计时器的 debounce(
    references/deferred-consistency.md
    )。
  6. <Activity>
    、
    <ViewTransition>
    、
    useEffectEvent
    的使用场景参见
    references/concurrent-ux.md
    。
  7. props 的形态参见
    references/component-apis.md
    ,命名与文件参见
    references/naming.md
    。

非同期の瀑布

异步瀑布

独立した処理を、前の結果を使わないのに順番に待たない。React の他の性能の話より先に、この節を当てる。詳細は
references/async.md
。
  • Effect なら
    Effect.all
    か
    Effect.forEach
    に
    { concurrency: "unbounded" }
    を渡す。順番が仕様なら
    { concurrency: 1 }
    と書く。省略しない。
  • Effect の外の Promise なら
    Promise.all
    。
  • 依存が一部だけのときは、依存しない側を先に始め、依存する側は
    Effect.flatMap
    で必要な値ができてから始める。両方を一つの
    Effect.all
    に載せる。
ts
const loaded = Effect.all(
  {
    config: fetchConfig,
    profile: fetchUser.pipe(Effect.flatMap((user) => fetchProfile(user.id))),
  },
  { concurrency: "unbounded" },
);
不要让彼此独立的任务在前一个任务的结果尚未返回时依次等待。在讨论其他 React 性能问题之前,应先检查这一部分。详情参见
references/async.md
。
  • 如果使用 Effect,则向
    Effect.all
    或
    Effect.forEach
    传入
    { concurrency: "unbounded" }
    。如果顺序有明确要求,则写入
    { concurrency: 1 }
    。不能省略。
  • 如果是 Effect 之外的 Promise,则使用
    Promise.all
    。
  • 当只有部分任务存在依赖时,先启动不依赖其他任务的部分;依赖任务则通过
    Effect.flatMap
    等待所需值就绪后再启动。两者都放入同一个
    Effect.all
    中。
ts
const loaded = Effect.all(
  {
    config: fetchConfig,
    profile: fetchUser.pipe(Effect.flatMap((user) => fetchProfile(user.id))),
  },
  { concurrency: "unbounded" },
);

採らない原典の箇所

不采用的原始资料内容

原典代わり
Next.js(
next/dynamic
、
after()
、React
cache()
をリクエストをまたいで使う)
TanStack Start のローダー
SWRTanStack Query
useState
/
useRef
でローディングや一時値を持つ
useMutation
、
useTransition
、Effect Atom
better-all
Effect.all
ハンドラを ref にしまう
useEffectEvent
Redux の Action / Reducer / SelectorEffect Atom と TanStack Query、FSD の
model
/
api
/
ui
不確かな API の形は react.dev の該当リファレンスを見る。原典の例を、上の表が使わないとしたフックのまま写さない。
原始资料替代方案
Next.js(
next/dynamic
、
after()
、跨请求复用 React
cache()
)
TanStack Start 的 loader
SWRTanStack Query
使用
useState
/
useRef
管理 loading 或临时值
useMutation
、
useTransition
、Effect Atom
better-all
Effect.all
将 handler 存入 ref
useEffectEvent
Redux 的 Action / Reducer / SelectorEffect Atom 与 TanStack Query,以及 FSD 的
model
/
api
/
ui
对于不确定的 API 形态,请查阅 react.dev 上对应的参考文档。不要直接照抄原始资料中仍使用上表明确弃用 hook 的示例。