1

这个问题与eslint-plugin-react-hooks

当我在 CodeSanbox 中使用 React Sandbox 时,我可以使用 props 对象的单个属性作为 useEffect 挂钩的依赖项:

示例 1:

useEffect(()=>{
  console.log('Running useEffect...');
  console.log(typeof(props.myProp));    // USING ONLY 'myProp' PROPERTY
},[ ]);                                 // EMPTY ARRAY

示例 1在 CodeSandbox 环境中给了我以下警告:

React Hook useEffect 缺少一个依赖项:'props.myProp'。包括它或删除依赖数组。(react-hooks/exhaustive-deps) eslint

如果我添加[props.myProp]到数组中,警告就会消失。

但是在我的本地环境中的 VSCode 中的相同示例 1,我收到以下警告

React Hook useEffect 缺少依赖项:'props'。包括它或删除依赖数组。但是,当任何道具发生变化时,“道具”会发生变化,因此首选的解决方法是在 useEffect 调用之外解构“道具”对象,并在 useEffect.eslint(react-hooks/exhaustive-deps) 中引用那些特定的道具

是问我我错过了完整的props对象。如果我添加[props.myProp]到数组中,警告不会消失。尽管代码按预期工作。

我希望我会在 VSCode 的本地环境中获得与 CodeSandbox 相同的行为。

会发生什么?有什么我可以改变的配置eslint-plugin-react-hooks吗?

包裹

开发:

"eslint": "^5.10.0",
"eslint-plugin-react": "^7.11.1",
"eslint-plugin-react-hooks": "^1.6.1",

常规的

"react": "^16.8.6",
"react-dom": "^16.8.6",

.eslintrc.json

{
  "root"  :true,
  "env": {
    "browser": true,
    "commonjs": true,
    "es6": true,
    "node": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:import/errors"
  ],
  "parser":"babel-eslint",
  "parserOptions": {
    "ecmaVersion": 8,
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx":true
    }
  },
  "plugins":[
    "react",
    "react-hooks"
  ],
  "rules": {
    "react/prop-types": 0,
    "semi": "error",
    "no-console": 0,
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "warn"
  },
  "settings": {
    "import/resolver" : {
      "alias" : {
        "map" : [
          ["@components","./src/components"],
          ["@constants","./src/constants"],
          ["@helpers","./src/helpers"]
        ],
        "extensions": [".js"]
      }
    }
  }
}
4

1 回答 1

3

这个问题的答案在这里得到了一些回答:https ://github.com/facebook/react/issues/16265#issuecomment-517518539

插件对它的看法不同的原因是因为props.whatever()你实际上是把props自己作为一个this值传递给whatever. 所以从技术上讲,它会看到陈旧的道具。

通过在调用之前阅读函数,您可以避免问题。

尽管答案说解构就是答案,但有一点需要注意。除了解决警告(99% 的情况)或破坏您的代码外,解构或重新分配将没有任何效果。如果你解构或重新分配,函数将没有this,如果这不是问题,那么警告是没有意义的。这是一个人为案例的演示,其中任何一个都很重要。

function bark() {
  console.log(`${this.name} barked.`);
}

const mac = {
  name: "mac",
  bark
};

const cheese = {
  name: "cheese",
  bark
};

const DogBark = props => {
  useEffect(() => props.dog.bark(), [props.dog.bark]);

  return null;
};

const Dog = () => {
  const [dog, setDog] = React.useState(mac);

  useEffect(() => setDog(cheese), []);

  // will cheese bark?
  return (
    <DogBark dog={dog} />
  );
};

奶酪不会吠叫。当您开始使用时,问题会变得更糟useCallback

const DogBarkByCallback = props => {
  const bark = React.useCallback(() => props.dog.bark(), [props.dog.bark]);
  // every dog should bark, and if the definition of 
  // bark changes even though the dog is the same, it should bark again
  useEffect(() => bark(), [props.dog, bark]); 

  return null;
};

在这种情况下,mac 会叫两次,因为回调没有改变。因此,解决方案是要么按照警告的建议确保[props.dog]在你的依赖数组中,要么知道你不需要this并解构或重新分配值来规避警告。

在控制台中演示:https ://codesandbox.io/s/exhaustive-deps-fn-mrdld

于 2020-04-24T15:49:27.883 回答