我的useEffect
功能组件中有以下挂钩,我只想使用一次(安装组件时),以便从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>
);
};
一个React文档说明指出,当您只希望效果在安装卸载时运行时,这是有效的做法:
如果要运行效果并仅将其清理一次(在挂载和卸载时),则可以传递一个空数组([])作为第二个参数。这告诉React您的效果不依赖于道具或状态的任何值,因此它不需要重新运行。这不是特殊情况,它直接取决于依赖项数组始终如何工作。
但是我收到以下create-react-app linter警告:
35:6 warning React Hook useEffect has a missing dependency: 'weaponOptions'. Either include it or remove the dependency array react-hooks/exhaustive-deps
weaponOptions
如果我将数组作为依赖项传递,则useEffect会触发数组是否发生更改,这会导致无限循环,因为钩子本身会更改武器选项状态。如果我省略了空数组参数,也会发生同样的事情。
这里正确的方法是什么?
我只想使用一次(安装组件时),以便从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 <></>;
};
但是,当您想使用useEffect
一次(这取决于一个状态)时,通常会使用布尔引用,如下所示:
const App = () => {
const [weaponOptions, setWeaponOptions] = useState(INITIAL);
const isFirstFetch = useRef(true);
useEffect(() => {
const fetchWeaponsOptions = async () => {...}
if (isFirstFetch.current) {
fetchWeaponsOptions();
isFirstFetch.current = false;
}
}, [weaponOptions]);
return <></>;
};
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句