eslint 访问了一个对象的属性 props.onClick 但提示 warning
🕐
eslint 访问了一个对象的属性 props.onClick,就等于间接依赖了整个 props 对象
我用最通俗、最本质、最彻底的方式给你讲清楚——
为什么 ESLint 会认为:你写了 props.onClick,就等于依赖了整个 props 对象?
这不是玄学,这是 JavaScript 语言特性 + React Hook 安全规则 共同决定的。
1. 先看一句最关键的话
在 JavaScript 里:
props.onClick
真正的执行顺序是:
- 先拿到
props这个对象本身 - 再从它身上读取
onClick属性
所以:
你不可能跳过 props 直接拿到 props.onClick
→ 你必须依赖 props,才能读取它的属性。
2. ESLint 担心的“致命风险”
ESLint 不是没事找事,它是在保护你。
看这个危险场景:
useCallback(() => {
props.onClick();
}, [props.onClick]);
假设:
- 第一次渲染:
props = { onClick: A } - 父组件重新渲染,整个 props 变成了新对象:
props = { onClick: A }(注意:onClick 没变,但 props 对象变了) - 你的闭包还抓着旧的 props 对象
- 虽然理论上没问题,但闭包捕获了旧对象引用
ESLint 说:
你捕获了旧对象,却只依赖属性,这不安全。
这就是它警告的原因。
3. 官方为什么强制推荐:解构?
因为解构能彻底消除风险。
const { onClick } = props; // 👈 把值取出来,变成独立变量
useCallback(() => {
onClick(); // 👈 直接用变量,不碰 props
}, [onClick]);
这样做:
- 不再需要读取任何对象
- 不再依赖
props - 只依赖确切用到的变量
- 闭包安全
- 性能最优
这就是 ESLint 拼命推荐它的原因。
4. 用一句话总结(你记这句就够了)
只要你写 props.xxx,你就一定依赖了 props 对象。
因为你必须先有对象,才能读属性。
ESLint 看到 props.xxx,就会要求你把 props 放进依赖。
但放 props 又会导致性能问题,
所以官方唯一正确解法:解构,不要用 props.xxx 进 Hook。
5. 最直观对比
❌ 不好(会触发 ESLint)
useCallback(() => {
props.onClick();
}, [props.onClick]);
✅ 完美(ESLint 满意)
const { onClick } = props;
useCallback(() => {
onClick();
}, [onClick]);
如果你愿意,我可以再给你讲:
为什么解构后,就不再依赖 props 了?
保证你彻底通透,再也不会被 ESLint 搞晕。