React Hook useEffect缺失依赖‘History’警告的解决咨询
解决React Hook useEffect的依赖缺失警告问题
这个警告是因为你的useEffect钩子内部用到了History对象,但没把它加入到依赖数组里——ESLint的react-hooks/exhaustive-deps规则会严格检查effect内部使用的所有外部变量,确保它们都被声明在依赖数组中,避免出现过时闭包的问题。
这里有两种简洁且合规的解决方式:
方案一:直接将History加入依赖数组(推荐)
useHistory返回的History实例在组件的整个生命周期内是稳定不变的(react-router-dom内部保证了这一点),所以把它加入依赖数组不会导致不必要的重渲染,完全符合React Hooks的规则。修改后的代码如下:
import {useContext, useEffect, useState} from 'react'; import {useHistory} from "react-router-dom"; import {MasterContext} from "../../Context/MasterProvider"; import LoginActions from "../../Context/Actions/LoginActions"; const useLoginForm = () => { const History = useHistory(); const [login, setLogin] = useState({}); const {AuthState: {Authentication: {Loading, Data, Error}}, AuthDispatch}=useContext(MasterContext); const FormData = (event) => { const { target: { value, name } } = event; setLogin({...login, [name]: value}); }; const FormValid = !login.email?.length || !login.password?.length; const FormSubmit = () => { LoginActions(login)(AuthDispatch); } useEffect(() => { // 用可选链简化嵌套判断,代码更简洁 if(Data?.user) { History.push("/"); } }, [Data, History]) // 这里添加History到依赖数组 return {login, FormData, FormValid, FormSubmit, Loading, Error, Data}; } export default useLoginForm;
方案二:用useRef保存History(适合特殊场景)
如果出于某些原因你不想把History加入依赖数组,可以用useRef来保存最新的History引用,这样即使History变化(实际几乎不会发生),effect也能拿到最新的实例:
import {useContext, useEffect, useState, useRef} from 'react'; import {useHistory} from "react-router-dom"; import {MasterContext} from "../../Context/MasterProvider"; import LoginActions from "../../Context/Actions/LoginActions"; const useLoginForm = () => { const History = useHistory(); const historyRef = useRef(History); // 实时保存最新的History引用 useEffect(() => { historyRef.current = History; }, [History]); const [login, setLogin] = useState({}); const {AuthState: {Authentication: {Loading, Data, Error}}, AuthDispatch}=useContext(MasterContext); const FormData = (event) => { const { target: { value, name } } = event; setLogin({...login, [name]: value}); }; const FormValid = !login.email?.length || !login.password?.length; const FormSubmit = () => { LoginActions(login)(AuthDispatch); } useEffect(() => { if(Data?.user) { historyRef.current.push("/"); } }, [Data]) return {login, FormData, FormValid, FormSubmit, Loading, Error, Data}; } export default useLoginForm;
总结:方案一是最直接且推荐的做法,它完全遵循React Hooks的规则,代码也更简洁。useHistory返回的实例稳定性有保障,不用担心加入依赖后会引发额外的渲染问题。
内容的提问来源于stack exchange,提问作者Ramy Mohamed
相关产品推荐
相关产品推荐

