警告“穷举”会不断询问完整的“道具”对象,而不是允许单个“道具”属性作为依赖项

时间:2019-07-31 11:25:38

标签: javascript reactjs react-hooks eslint-plugin-react-hooks

此问题与eslint-plugin-react-hooks

有关

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

示例1:

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

示例1在CodeSandbox环境中为我提供了以下警告

  

反应挂钩useEffect缺少依赖项:'props.myProp'。包括它或删除依赖项数组。 (反应钩/穷尽滴水)结冰

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

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

  

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

问我缺少完整的props对象。而且,如果我将[props.myProp]添加到数组,则警告不会消失。尽管代码按预期运行。

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

可能会发生什么?我可以在eslint-plugin-react-hooks中进行任何配置更改吗?

包装

DEV:

"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"]
      }
    }
  }
}

3 个答案:

答案 0 :(得分:2)

这个问题的答案在这里有些回答: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并进行变形或重新分配该值来避免警告。< / p>

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

答案 1 :(得分:1)

您是否考虑过破坏财产?

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

答案 2 :(得分:0)

我了解发生了什么事。 (我认为)这不是错误。

此代码:

useEffect(()=>{
  function someFunction() {
    props.whatever();                  // CALLING A FUNCTION FROM PROPS
  }
},[ ]);

导致此警告:

  

反应挂钩useEffect缺少依赖项:'props'。包括它或删除依赖项数组。但是,当 any prop更改时,“ props”也会更改,因此首选解决方法是在useEffect调用之外对“ props”对象进行解构,并引用useEffect中的那些特定props。 (react-hooks / exhaustive-deps)eslint


这段代码:

useEffect(()=>{
  function someFunction() {
    props.whatever;                          // ACCESSING A PROPERTY FROM PROPS
  }
},[]);

导致此警告:

  

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


我不确定为什么,但是当您从props调用方法或从property调用props时,插件对它的看法会有所不同。