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

Javascript 将空数组作为第二个参数传递时,React Hook useEffect缺少依赖项,javascript,reactjs,Javascript,Reactjs,我的功能组件中有以下useffecthook,我只想使用一次(当组件挂载时),以便从API加载一些数据: const Gear = () => { const [weaponOptions, setWeaponOptions] = useState([ { key: "0", label: "", value: "null" } ]); const [weapon, setWeapon] = useState("null");

我的功能组件中有以下
useffect
hook,我只想使用一次(当组件挂载时),以便从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.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>
  );
};
const Gear=()=>{
const[weaponOptions,setWeaponOptions]=useState([
{
密钥:“0”,
标签:“,
值:“null”
}
]);
常量[武器,设置武器]=使用状态(“空”);
useffect(()=>{
console.log(“Gear.tsx useffect”);
const fetchWeaponsOptions=async():Promise=>{
const weaponsData=等待获取武器();
const newWeaponOptions:DropdownOptionType[]=[
…武器选择,
…weaponsData.map({id,name})=>{
返回{
关键字:id,
标签:名称,
值:id
};
})
];
设置武器选项(新武器选项);
};
获取武器();
}, []);
//TODO在更改时添加武器下拉列表,选择武器状态
const handleWeaponChange=({value}:DropdownOptionType):void=>{
设定武器(价值);
};
返回(
齿轮:
);
};
A声明,当您只希望在卸载时运行效果时,这是有效的做法:

如果你想运行一个特效并且只清理一次(在安装和 卸载),可以将空数组([])作为第二个参数传递。这 告诉React您的效果不依赖于道具的任何值 或状态,因此它永远不需要重新运行。这不是一个特殊的问题 案例-它直接从依赖项数组始终 工作

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

35:6警告效果缺少依赖项:“武器选项”。包括它或删除依赖项数组react hooks/deps

如果我将
weaponOptions
数组作为依赖项传递,则会触发useEffect,因为钩子本身会更改weaponOptions状态,从而导致无休止的循环。如果省略空数组参数,也会发生同样的情况


正确的方法是什么?

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

我只想使用一次(当组件挂载时),以便从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 <></>;
};

它会的,请告诉我们武器选项从哪里来from@DennisVashsry,在最初的问题中添加了整个功能组件代码,以使问题更加清晰。这非常有意义:)。谢谢
const App = () => {
  const [weaponOptions, setWeaponOptions] = useState(INITIAL);

  const isFirstFetch = useRef(true);

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

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

  return <></>;
};