clean-react-hooks
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseClean Hooks
整洁的Hooks
Hooks should make stateful behavior explicit. Effects are for synchronization with systems outside React, not for deriving ordinary render data.
Hooks应使有状态行为清晰明确。Effect用于与React外部系统同步,而非推导普通渲染数据。
R4: Effects
R4: Effects
Use for:
useEffect- Subscriptions and cleanup
- Browser APIs and imperative widgets
- Network calls when the project does not use a data-fetching library
- Synchronizing React state with an external system
Do not use for values that can be computed during render.
useEffecttsx
// Bad - derived state via effect
const [fullName, setFullName] = useState("");
useEffect(() => {
setFullName(`${firstName} ${lastName}`);
}, [firstName, lastName]);
// Good - derived during render
const fullName = `${firstName} ${lastName}`;使用的场景:
useEffect- 订阅及清理操作
- 浏览器API和命令式组件
- 项目未使用数据获取库时的网络请求
- 将React状态与外部系统同步
不要将用于可在渲染期间计算的值。
useEffecttsx
// Bad - derived state via effect
const [fullName, setFullName] = useState("");
useEffect(() => {
setFullName(`${firstName} ${lastName}`);
}, [firstName, lastName]);
// Good - derived during render
const fullName = `${firstName} ${lastName}`;Dependencies
依赖项
- Treat the dependency array as a correctness contract.
- Do not suppress exhaustive-deps without explaining the external invariant.
- Stabilize callbacks only when identity matters to a child, subscription, or memoized computation.
- Prefer moving logic inside the effect over hiding dependencies.
- 将依赖数组视为正确性契约。
- 不要在未说明外部不变量的情况下禁用exhaustive-deps检查。
- 仅当回调的标识对子组件、订阅或记忆化计算至关重要时,才稳定回调。
- 优先将逻辑移至effect内部,而非隐藏依赖项。
R8: Custom Hooks
R8: 自定义Hooks
Create a custom hook when behavior is reusable and stateful, or when it gives a complex effect a clear boundary.
tsx
function useWindowSize(): WindowSize {
const [size, setSize] = useState(getWindowSize);
useEffect(() => {
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
function handleResize() {
setSize(getWindowSize());
}
}, []);
return size;
}Keep hook APIs small. Return named objects for multiple values unless tuple ordering is a local convention.
当行为可复用且带有状态,或需要为复杂effect划分清晰边界时,创建自定义hook。
tsx
function useWindowSize(): WindowSize {
const [size, setSize] = useState(getWindowSize);
useEffect(() => {
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
function handleResize() {
setSize(getWindowSize());
}
}, []);
return size;
}保持hook的API简洁。除非元组排序是本地约定,否则返回命名对象以包含多个值。
Refs
Refs
Use refs for imperative handles, DOM nodes, and mutable values that should not trigger render. Do not use refs to sidestep normal state flow.
使用refs处理命令式句柄、DOM节点以及不应触发渲染的可变值。不要使用refs规避正常的状态流。
Common Mistakes
常见错误
- Using effects to copy props into state.
- Adding empty dependency arrays to "run once" while reading changing values.
- Using or
useMemoeverywhere without a measured reason.useCallback - Returning unstable object shapes from hooks that consumers put into dependency arrays.
- 使用effect将props复制到state中。
- 添加空依赖数组以“仅运行一次”,却读取变化的值。
- 无合理依据地到处使用或
useMemo。useCallback - 从hook返回不稳定的对象结构,而消费者会将其放入依赖数组中。