我在我的应用上收到一条警告消息,并且我尝试了很多尝试将其删除,但均未成功。错误消息:
反应挂钩useEffect缺少依赖项:'updateUserData'。 包括它或删除依赖项数组 反应钩/详尽的下降
我不想在注释中排除它以避免出现此问题,但我想以“最佳实践”的方式来解决它。
我想调用该更新程序函数并更新我的组件,以便可以在其他组件中共享该上下文。
那么...我在做什么错? (非常欢迎对其余代码进行任何代码审查!)
感谢一百万!
如果我将[]作为useEffect的第二个参数添加,则会收到警告,而将其删除则会出现无限循环。
还添加[updateuserData]会导致无限循环。
import React, { useState } from "react";
import UserContext from "./UserContext";
interface iProps {
children: React.ReactNode
}
const UserProvider: React.FC<iProps> = (props) => {
// practice details
const [userState, setUserState] = useState({
id'',
name: ''
});
// practice skills
const [userProfileState, setuserProfileState] = useState([]);
// user selection
const [userQuestionsState, setuserQuestionsState] = useState({});
return (
<UserContext.Provider value={{
data: {
user: userState,
userProfile: userProfileState,
questions: userQuestionsState
},
updateuserData: (id : string) => {
// call 3 services with axios in parallel
// update state of the 3 hooks
}
}}
>
{props.children}
</UserContext.Provider>
);
};
export default UserProvider;
const UserPage: React.FC<ComponentProps> = (props) => {
const {data : {user, profile, questions}, updateUserData}: any = useContext(UserContext);
useEffect(() => {
// update information
updateUserData("abcId")
}, []);
return <div>...</div>
}
想法如下:
我有上下文
我为该内容创建了提供程序
该上下文公开了数据和一个更新程序功能
我在带有useEffect钩子的组件中使用该提供程序,并得到警告
我想保留有关在提供程序内部获取和更新上下文的所有逻辑,因此,我不会在需要它的其他组件上复制所有逻辑。
答案 0 :(得分:1)
首先,无限循环是由以下事实引起的:您的上下文正在更新,这导致您的组件被重新呈现,这又更新了您的上下文,这导致您的组件被重新呈现。添加依赖项可以防止此循环,但是在您的情况下,这并不是因为您的上下文更新时会提供一个全新的updateuserData
,因此ref相等性检查会检测到更改并在您不进行更改时触发更新不想。
一种解决方案是使用以下方法更改在updateUserState
中创建UserProvider
的方式。 useCallback
传递相同的功能,除非其中一个依赖项更改:
const UserProvider: React.FC<iProps> = (props) => {
// practice details
const [userState, setUserState] = useState({
id'',
name: ''
});
// practice skills
const [userProfileState, setuserProfileState] = useState([]);
// user selection
const [userQuestionsState, setuserQuestionsState] = useState({});
const updateuserData = useCallback(id=>{
// call your services
}, [userState, userProfileState, userQuestionsState])
return (
<UserContext.Provider value={{
data: {
user: userState,
userProfile: userProfileState,
questions: userQuestionsState
},
updateuserData
}}
>
{props.children}
</UserContext.Provider>
);
};