React useEffect发布时触发react-hooks/exhaustive-deps错误求助
解决React Hooks的exhaustive-deps lint报错问题
错误原因
你遇到的react-hooks/exhaustive-deps报错,是ESLint的规则要求:useEffect的依赖数组必须包含所有在effect内部(以及内部调用的函数里)用到的外部变量、状态或函数。
看报错的代码:
useEffect里调用了load函数,load又调用了populateTable1Data和populateTable2Data- 这两个函数依赖了
props.id1、props.id2、apiurl、setTable1Data、setTable2Data、setLoading这些外部值,但你的useEffect依赖数组是空的[],所以触发了lint规则。
另一个组件的代码其实也不符合规则,只是可能因为lint配置差异或函数依赖的变量没被检测到,暂时没报错而已。
修复步骤
第一步:修正axios请求的语法错误
你代码里的axios.get(apiurl + { params: { id: props.id1 } })写法错误,对象和字符串拼接会得到类似apiurl[object Object]的无效地址,正确写法是把参数作为第二个参数传入:
// 修正后的请求写法 var response = await axios.get(apiurl, { params: { id: props.id1 } });
populateTable2Data里的axios请求也要做同样修改。
第二步:修复useEffect的依赖问题
有两种常用修复方式:
方式一:将内部函数移到useEffect内
把populateTable1Data、populateTable2Data和load都放到useEffect内部,明确追踪所有依赖:
useEffect(() => { const populateTable1Data = async () => { var response = await axios.get(apiurl, { params: { id: props.id1 } }); var data = await response.data; setTable1Data(data); }; const populateTable2Data = async () => { var response = await axios.get(apiurl, { params: { id: props.id2 } }); var data = await response.data; setTable2Data(data); setLoading(false); }; const load = async () => { await populateTable1Data(); await populateTable2Data(); setLoading(false); }; load(); }, [apiurl, props.id1, props.id2, setTable1Data, setTable2Data, setLoading]); // 把所有用到的外部依赖都加入数组
方式二:用useCallback包裹函数
如果需要在useEffect外部复用这两个populate函数,可以用useCallback包裹,确保函数引用稳定,并传入对应依赖:
const populateTable1Data = useCallback(async () => { var response = await axios.get(apiurl, { params: { id: props.id1 } }); var data = await response.data; setTable1Data(data); }, [apiurl, props.id1, setTable1Data]); const populateTable2Data = useCallback(async () => { var response = await axios.get(apiurl, { params: { id: props.id2 } }); var data = await response.data; setTable2Data(data); setLoading(false); }, [apiurl, props.id2, setTable2Data, setLoading]); useEffect(() => { const load = async () => { await populateTable1Data(); await populateTable2Data(); setLoading(false); }; load(); }, [populateTable1Data, populateTable2Data, setLoading]); // 依赖数组放入被useCallback包裹后的函数
第三步:(可选)忽略单个useEffect的lint报错
如果你确定只需要在组件挂载时执行一次,不需要依赖更新时重新执行,可以在useEffect上方加注释忽略规则,但不推荐这种做法——可能导致依赖更新时不触发逻辑,引发隐藏bug:
// eslint-disable-next-line react-hooks/exhaustive-deps useEffect(() => { // ... 你的代码 }, []);
内容的提问来源于stack exchange,提问作者JustMe
相关产品推荐
相关产品推荐

