当前位置: 首页 > 知识库问答 >
问题:

将空数组作为第二个参数传递时,React Hook useEffect缺少依赖项

益智明
2023-03-14

我的功能组件中有以下useffecthook,我只想使用一次(当组件挂载时),以便从API加载一些数据:

const Gear = () => {
  const [weaponOptions, setWeaponOptions] = useState([
    {
      key: "0",
      label: "",
      value: "null"
    }
  ]);
  const [weapon, setWeapon] = useState("null");

  useEffect(() => {
    console.log("Gear.tsx useEffect");

    const fetchWeaponsOptions = async (): Promise<void> => {
      const weaponsData = await getWeapons();
      const newWeaponOptions: DropdownOptionType[] = [
        ...weaponOptions,
        ...weaponsData.html" target="_blank">map(({ id, name }) => {
          return {
            key: id,
            label: name,
            value: id
          };
        })
      ];
      setWeaponOptions(newWeaponOptions);
    };

    fetchWeaponsOptions();
  }, []);

  // TODO add weapon dropdown on change, selected weapon state
  const handleWeaponChange = ({ value }: DropdownOptionType): void => {
    setWeapon(value);
  };

  return (
    <div>
      <h2>Gear:</h2>
      <Dropdown
        defaultValue={weapon}
        label="Weapon"
        name="weapon"
        options={weaponOptions}
        onChange={handleWeaponChange}
      />
    </div>
  );
};

React留档说明,当您只希望效果在挂载卸载时运行时,这是有效的做法:

如果您想运行一个效果并只清除它一次(在挂载和卸载时),您可以传递一个空数组([])作为第二个参数。这告诉React,你的效果不依赖于道具或状态的任何值,所以它永远不需要重新运行。这不是作为特例处理的——它直接遵循依赖数组的工作方式。

但我收到了以下create react应用程序linter警告:

35:6警告React Hook use效应有一个缺失的依赖项:武器选项。要么包含它,要么删除依赖数组report-追踪器/穷举-deps

如果我将其作为依赖项传递,则当武器选项数组发生更改时,会触发use效应,因为钩子本身会更改武器选项状态,从而导致无休止的循环。如果我省略空数组参数,也会发生同样的事情。

这里的正确方法是什么?

共有2个答案

仲孙华奥
2023-03-14

正如你所看到的,这不是一个错误,而是一个警告。React告诉您正在使用weaponOptions内部useffect,但您没有将其作为依赖项传递。同样,这只是一个警告,你不必这么做。

耿永寿
2023-03-14

我只想使用一次(当组件挂载时),以便从API加载一些数据

因此,根据您的逻辑,您不需要依赖组件的状态:

const INITIAL = [
  {
    key: '0',
    label: '',
    value: 'null'
  }
];

const App = () => {
  const [weaponOptions, setWeaponOptions] = useState(INITIAL);

  useEffect(() => {
    const fetchWeaponsOptions = async () => {
      const weaponsData = await getWeapons();
      const weaponsOptions = [
        ...INITIAL, // No state dependency needed
        ...weaponsData.map(({ id, name }) => {
          return {
            key: id,
            label: name,
            value: id
          };
        })
      ];
      setWeaponOptions(weaponsOptions);
    };

  }, []);

  return <></>;
};

但是,当您想使用useffect一次时,使用布尔引用是很常见的,这取决于一个状态,如下所示:

const App = () => {
  const [weaponOptions, setWeaponOptions] = useState(INITIAL);

  const isFirstFetch = useRef(true);

  useEffect(() => {
    const fetchWeaponsOptions = async () => {...}

    if (isFirstFetch.current) {
      fetchWeaponsOptions();
      isFirstFetch.current = false;
    }
  }, [weaponOptions]);

  return <></>;
};
 类似资料:
  • 问题内容: 我可以将数组作为url参数传递的最佳方法是什么?我在想这是否可能: 还是这样: 香港专业教育学院阅读示例,但我发现它很混乱: 问题答案: 有一个非常简单的解决方案:。它把您的查询参数作为一个关联数组: 将返回 为您处理所有必需的转义(=> 和=> ),因此此字符串等于。

  • 我们创建了一个公共类,其中RestTemplate作为参数传递。此rest模板用于促进: 发布实体 交换 但是,由于它在公共类中不是Autowyah,我无法创建模拟RestTemplate的单元测试。有没有解决这个问题的方法? 设置: Spring boot项目A-启动rest集成并使用公共类。该项目A实例化@Autowired RestTemplate rest模板,并将其作为参数传递给公共类方

  • 我刚刚将我的项目升级到gradle 7,并且遇到了缺失的可传递依赖项。我试着改变我的身材。gradle文件在依赖项中使用“api”,但这并没有修复它。 projectA依赖于projectB,projectB依赖于projectC。 projectA-build。格拉德尔 projectB-构建。格拉德尔 ProjectA编译良好,但有运行时错误-从project ectC获取类的ClassNot

  • 问题内容: 有没有一种方法可以创建对象数组作为构造函数或方法的一部分?我真的不知道该如何措辞,因此我提供了一个示例。我有一个枚举,并且其中一个字段是数字数组。这是我尝试过的: 编译器说方括号{}无效,应将其删除。有没有一种方法可以将数组作为参数传递而无需事先创建对象数组? 问题答案: 您可以尝试使用。

  • 问题内容: 我想使用数组作为参数调用一个函数: 有路过的内容的一种更好的方式进入? 问题答案: const args = [‘p0’, ‘p1’, ‘p2’]; call_me.apply(this, args); 请参阅MDN文档。 如果环境支持ECMAScript6,则可以改用传播参数:

  • 问题内容: 如何在不执行“父”函数或不使用函数的情况下将函数作为参数传递?(因为我已经读到它是不安全的。) 我有这个: 它可以工作,但是问题是在调用函数时触发,而不是在函数中使用时触发。 根据我所读的内容,我可以使用来解决它,但这不是最佳实践。如何在JavaScript中将函数作为参数传递? 问题答案: 您只需要删除括号: 然后,这将传递函数而不先执行它。 这是一个例子: