reactjs / reactjs/react.dev

[Suggestion]: Document that hooks can be called after a conditional `throw`

未關閉
#7,291 0 則留言 10 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

type: documentation
主要語言
JavaScript
星號
11.8k
分支
7.9k
平均合併
1 天 11 小時
30 天內合併 PR
11

描述

Summary

I don't believe it is documented anywhere that calling a hook after a conditional throw statement is not a violation of the rules of hooks. If this is a valid pattern, it should be documented. If it is not, the Eslint rule rules-of-hooks should warn for it.

Page

Rules of hooks

Details

I realised this is effectively the pattern when using Next.js app router notFound(), which throws an Error in the component render. I had assumed this not being flagged by the rules-of-hooks was a limitation of the Next.js eslint plugin, but actually, this is not flagged as an issue with a standard throw:

const Component = ({ someOtherCondition }) => {
  const [foo, setFoo] = useState();

  if (someOtherCondition) throw new Error();

  const [bar, setBar] = useState();

  return (<>...</>);
};

My assumption is this is a valid pattern as if someOtherCondition becomes true, the error will be thrown up the call stack to the nearest error boundary, and the render that was in-progress will be discarded. There is not a case to have this conditional throw call more hooks than the previous render, only less. The rules of hooks state:

It’s not supported to call Hooks (functions starting with use) in any other cases, for example:

🔴 Do not call Hooks inside conditions or loops.
🔴 Do not call Hooks after a conditional return statement.

In the example above, the second useState call comes after a conditional throw statement. Not quite either of the cases in documentation.

If this is a valid pattern, it should be mentioned in the docs, with potential warnings about it not being a recommended workaround to conditionally call hooks (as there is no way to resume execution of the other path of the conditional once an error is thrown from the component).

If this isn't a valid pattern, it should be flagged by the eslint rule.

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

研究方向

從 Rules of Hooks 頁面以及 issue 中描述的 rules-of-hooks 文件化行為開始。重現條件 throw 範例,然後判斷頁面是否需要澄清,或 ESLint 規則是否應該變更;完成的標準是,該行為及其預期指引已獲得解決,並反映在適當的位置。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
eslint, javascript, next.js, react
領域
documentation
Issue 類型
文件
難度
4/5
預估耗時
3-5 天
活躍度
停滯
描述清晰度
需要釐清
新手友好度
35/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。