eslint 访问了一个对象的属性 props.onClick 但提示 warning

🕐
eslint 访问了一个对象的属性 props.onClick,就等于间接依赖了整个 props 对象

我用最通俗、最本质、最彻底的方式给你讲清楚——

为什么 ESLint 会认为:你写了 props.onClick,就等于依赖了整个 props 对象?

这不是玄学,这是 JavaScript 语言特性 + React Hook 安全规则 共同决定的。


1. 先看一句最关键的话

在 JavaScript 里:

props.onClick

真正的执行顺序是:

  1. 先拿到 props 这个对象本身
  2. 再从它身上读取 onClick 属性

所以:
你不可能跳过 props 直接拿到 props.onClick
→ 你必须依赖 props,才能读取它的属性。


2. ESLint 担心的“致命风险”

ESLint 不是没事找事,它是在保护你

看这个危险场景:

useCallback(() => {
  props.onClick();
}, [props.onClick]); 

假设:

  1. 第一次渲染:props = { onClick: A }
  2. 父组件重新渲染,整个 props 变成了新对象props = { onClick: A } (注意:onClick 没变,但 props 对象变了)
  3. 你的闭包还抓着旧的 props 对象
  4. 虽然理论上没问题,但闭包捕获了旧对象引用

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 搞晕。