[英]React useContext hook: context becomes null on page reload
我有以下 UserContext.js 文件,它将当前登录的用户存储到用户 object 和设置器 function 中。 在我的配置文件组件中,我想使用当前登录用户的信息预先填充我的输入字段,我应该使用 useContext 挂钩来获取这些信息。
如果我从主页正常导航到个人资料页面,该应用程序工作正常,但是当我尝试在个人资料页面中直接访问 /profile 或重新加载页面时,我看到我的上下文在一瞬间变得未定义(如所见由console.log),在它加载一个值之前。 这会导致 useEffect() 钩子和 initializeFields() function 失败,因为属性是 null。
我想要发生的是能够无缝加载当前登录的用户,并在应用程序的其他组件中全局使用它。 将父组件中的用户 object 作为 props 传递是不可行的,因为实际上,我的应用程序有一些组件很深,并且 prop-drilling 不是一个非常优雅的解决方案。
const UserContext = React.createContext({
user: {},
setUser: (user) => {},
});
在 App.js 组件中:
const App = (props) => {
const [user, setUser] = useState(null);
return (
<div className="app">
<UserContext.Provider value={{ user, setUser }}>
<Switch>
<Route path="/profile" exact component={Profile} />
</Switch>
</UserContext.Provider>
</div>
);
Profile.js 组件:
const DashboardProfileModal = (props) => {
const userContext = useContext(UserContext);
const [name, setName] = useState();
const [username, setUsername] = useState();
const [password, setPassword] = useState();
const [address, setAddress] = useState();
console.log(userContext)
useEffect(() => {
initializeFields();
});
const initializeFields = () => {
setName(userContext.user.name);
setUsername(userContext.user.username);
setPassword(userContext.user.password);
setAddress(userContext.user.address);
};
我相信您面临的问题是因为您在App
组件上声明了提供程序。 如果您希望整个应用程序可以全局访问它,您应该将它放在index.js
文件中,并包装App
组件。 就像是:
ReactDOM.render(
<React.StrictMode>
<UserContext.Provider>
<App />
</UserContext.Provider>
</React.StrictMode>,
document.getElementById("root")
)
您可以执行以下操作,并在尝试使用之前确保 userContext 可用。
您还应该至少通过添加[]
使useEffect
在页面加载时运行一次(否则它会在每次渲染时不断触发)。 我还将userContext
添加为useEffect
的依赖项,然后检查userContext
和name
。 这意味着它将确保userContext
在尝试运行您的方法之前不是null
。
然后我还包括!name
检查,以便我们可以确保在首次设置 state 后它不会继续尝试运行您的方法。
const DashboardProfileModal = (props) => {
const userContext = useContext(UserContext);
const [name, setName] = useState();
const [username, setUsername] = useState();
const [password, setPassword] = useState();
const [address, setAddress] = useState();
console.log(userContext)
useEffect(() => {
if(userContext && !name){
initializeFields();
}
},[userContext]);
const initializeFields = () => {
setName(userContext.user.name);
setUsername(userContext.user.username);
setPassword(userContext.user.password);
setAddress(userContext.user.address);
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.