facebook / react · Issue No. 37665
eslint-plugin-react-hooks are you using?7.0.0 (also reproducible on earlier versions)
react-hooks/rules-of-hooks should flag hook calls that appear after an early return inside a component whose name contains non-ASCII (CJK) characters — the same way it does for ASCII-named components.
When the component name is a CJK identifier (common in our Chinese-language codebase), rules-of-hooks produces no diagnostics for early-return-followed-by-hooks. Worse, enabling the rule yields hundreds of false positives that look like "hook called outside a component" — presumably because the plugin's component-detection heuristic doesn't recognize non-ASCII function names as components.
This forced us to disable rules-of-hooks entirely, which removed static protection for exactly one class of real bug we shipped to production: a useCallback added after a loading-state early return crashed with React error #310 ("Rendered more hooks...") on the first render where the condition flipped. tsc and our eslint setup (rule off) could not catch it.
// 中文组件名 — rules-of-hooks stays silent on the violation below
export default function 双池视图() {
const [切面, 设置切面] = useState<切面>('有待办');
const [载荷, 设置载荷] = useState<载荷 | null>(null);
if (三池查询.isPending || !载荷) return <p>正在读取…</p>; // early return
const 店名 = useCallback((id: number) => ids[id] ?? `店铺 ${id}`, []); // ← not flagged
...
}
Compare: renaming the component to PoolView makes the rule flag the useCallback after the early return as expected. A minimal standalone repro is available if useful.
Support non-ASCII (at least CJK) identifiers in the component-detection heuristic used by rules-of-hooks, or expose an option to treat "hook called in a function whose name starts with use / a top-level function in a component module" as a component regardless of name script.
Relay reads this issue against the repository's contribution signals: the files it is likely to touch, how the maintainers triage work this size, and what the first contribution would exercise.
The full analysis for this issue is still being assembled. Until then, the description above and the thread on GitHub are the most reliable context.