【问题标题】:React Hook useEffect has missing dependencies: 'colors' and 'options'. Either include them or remove the dependency arrayReact Hook useEffect 缺少依赖项:“颜色”和“选项”。包括它们或删除依赖数组
【发布时间】:2021-05-07 01:35:58
【问题描述】:

我正在尝试在发布之前进行我的第一个 React 构建并遇到这样的 React Hook 错误: “React Hook useEffect 缺少依赖项:'colors' 和 'options'。要么包含它们,要么删除依赖项数组。

我的组件在最后一行显示错误。我做错了什么?

function MemoryGame({ options, setOptions, highScore, setHighScore }) {
  const [game, setGame] = useState([]);
  const [flippedCount, setFlippedCount] = useState(0);
  const [flippedIndexes, setFlippedIndexes] = useState([]);

  const colors = [
    `url(${Background1})`,
    `url(${Background13})`,
    `url(${Background3})`,
    `url(${Background4})`,
    `url(${Background5})`,
    `url(${Background6})`,
    `url(${Background7})`,
    `url(${Background8})`,
    `url(${Background9})`,
    `url(${Background14})`,
    `url(${Background11})`,
    `url(${Background12})`,
  ];

  useEffect(() => {
    const newGame = [];
    for (let i = 0; i < options / 2; i++) {
      const firstOption = {
        id: 2 * i,
        colorId: i,
        color: colors[i],
        flipped: false,
      };
      const secondOption = {
        id: 2 * i + 1,
        colorId: i,
        color: colors[i],
        flipped: false,
      };

      newGame.push(firstOption);
      newGame.push(secondOption);
    }

    const shuffledGame = newGame.sort(() => Math.random() - 0.5);
    setGame(shuffledGame);
  }, []);

我刚刚添加了[colors, options],但现在得到了这个:'colors' 数组使 useEffect Hook(在第 137 行)的依赖关系在每次渲染时都会发生变化。将它移到 useEffect 回调中。或者,将 'colors' 的初始化封装在它自己的 useMemo() Hook 中。

现在我尝试将 const colors 移动到 useEffect 并且变得不确定。我还做错了什么?

  useEffect(() => {
    const colors = [
      `url(${Background1})`,
      `url(${Background13})`,
      `url(${Background3})`,
      `url(${Background4})`,
      `url(${Background5})`,
      `url(${Background6})`,
      `url(${Background7})`,
      `url(${Background8})`,
      `url(${Background9})`,
      `url(${Background14})`,
      `url(${Background11})`,
      `url(${Background12})`,
    ];
    const newGame = [];
    for (let i = 0; i < options / 2; i++) {
      const firstOption = {
        id: 2 * i,
        colorId: i,
        color: colors[i],
        flipped: false,
      };
      const secondOption = {
        id: 2 * i + 1,
        colorId: i,
        color: colors[i],
        flipped: false,
      };
      newGame.push(firstOption);
      newGame.push(secondOption);
    }
    const shuffledGame = newGame.sort(() => Math.random() - 0.5);
    setGame(shuffledGame);
  }, [colors, options]);

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    不要忽略警告,它的存​​在是有充分理由的。这样做的目的是通知您,您正在使用对在钩子本身之外定义的变量的引用,这些变量可能会发生变异并使您处于陈旧状态。

    useEffect 钩子接受 2 个参数,其中第二个是一个依赖数组——在你的例子中是一个空的。基于这个数组,react 知道何时应该执行 useEffect 中的回调。在您的情况下提供一个空数组将导致回调只运行一次,在组件的初始渲染之后并且不会再运行,无论您的组件发生什么变化。因此,即使您更改了 colorsoptions 引用,钩子也不会执行,并且您将处于陈旧状态,因此会发出警告。但是,您的代码实际上取决于这两个引用,因此您应该将它们放在依赖数组中,以指示 react 在它们中的任何一个更改时重新运行回调函数(即使它们是常量并且您知道不会更改) .所以,使用这个:

      useEffect(() => {
        const newGame = [];
        for (let i = 0; i < options / 2; i++) {
          const firstOption = {
            id: 2 * i,
            colorId: i,
            color: colors[i],
            flipped: false,
          };
          const secondOption = {
            id: 2 * i + 1,
            colorId: i,
            color: colors[i],
            flipped: false,
          };
    
          newGame.push(firstOption);
          newGame.push(secondOption);
        }
    
        const shuffledGame = newGame.sort(() => Math.random() - 0.5);
        setGame(shuffledGame);
      }, [colors, options]);
    

    基本上,如果一个变量(包括函数)只在useEffect回调中使用,你应该在内部定义它,你可以跳过将它添加到依赖数组中,因为它可以在内部跟踪它。 在极少数情况下,当您仅依赖于 useEffect 的变量的初始状态(之后可能发生变异)并且您只想在组件“设置”上运行一次挂钩时,您应该跳过将其添加到依赖项数组并且不会导致它重新执行。

    【讨论】:

    • 这是有道理的。我刚刚添加了[colors, options],但现在得到了这个:'colors' 数组使 useEffect Hook(在第 137 行)的依赖关系在每次渲染时都会发生变化。将它移到 useEffect 回调中。或者,将 'colors' 的初始化包装在它自己的 useMemo() Hook 中
    • BackgroundX 变量来自哪里?就像我在帖子中所说,如果您只在 useEffect 中使用引用,只需在此处定义它,就像您的警告状态一样。
    • 我编辑了我的问题,包括我做了什么。现在它显示'colors' is not defined。这里有点困惑。
    • @virtualbis 从依赖数组中移除 colors 引用。
    • 成功了。开始更好地理解并修复了几个类似的问题。谢谢。
    【解决方案2】:

    这是您的 es-lint 警告您,它认为您在依赖项数组中缺少这些项目。请务必注意,这仅显示错误,因为您的 IDE 设置在 linting 错误时编译失败。

    我对这条规则的经验是它非常不一致。例如:有时您希望 useEffect 根据某些条件触发,而不是根据其他条件触发。如果其中一个参数由于该触发器而发生更改(即在 useEffect 内发生突变),您将收到此 es-lint 警告。

    我的建议:更改您的 IDE 设置,以便此警告仍然允许您进行编译。这可以通过修改 eslint 配置中的规则来更改。每当您看到此警告时,请仔细检查以确保您的 useEffect 以正确的方式运行,并且您实际上没有丢失任何依赖项。如果是这种情况,请在 useEffect 挂钩顶部添加 es-lint 忽略。

    【讨论】:

      【解决方案3】:

      你需要在数组依赖中添加颜色和选项

       const shuffledGame = newGame.sort(() => Math.random() - 0.5);
          setGame(shuffledGame);
        }, [colors,options]);
      

      或者您可以使用 // eslint-disable-next-line 禁用规则

          setGame(shuffledGame);
      
        // eslint-disable-next-line
        }, []);
      

      【讨论】:

        猜你喜欢
        • 2020-07-19
        • 2020-11-05
        • 1970-01-01
        • 2021-10-29
        • 2020-05-31
        • 1970-01-01
        • 2021-08-24
        • 2023-04-09
        • 1970-01-01
        相关资源
        最近更新 更多