目标是在用户登录时能够访问任何组件中的用户数据,因此<UserProvider>
被 Package 在<App/>
周围。
问题是,在用户成功登录后,console.log("UserContext.js", res.data);
仅在刷新页面时记录用户的数据。
我知道这是由于异步的东西在幕后进行,但我不能把我的手指到底是什么问题。
我该怎么解决?
下面是UserContext.js
:
import { createContext, useContext, useState, useEffect } from 'react';
import ApiClient from "./ApiClient";
// Create the context
const UserContext = createContext();
// Custom hook to access the context
export const useUserContext = () => useContext(UserContext);
// Provider component to wrap the app and provide the context value
export const UserProvider = ({ children }) => {
const [userId, setUserId] = useState('');
const [name, setName] = useState('');
const headers = {
"Accept": 'application/json',
"Authorization": `Bearer ${localStorage.getItem('token')}`
};
const fetchUserData = () => {
ApiClient.get('get-user-data', {headers})
.then(res => {
console.log("UserContext.js", res.data);
setUserId(res.data.UserID);
setName(res.data.name);
}).catch(err => {
console.log(err);
});
}
useEffect(fetchUserData,[])
const contextValue = {
userId,
name,
refreshUserData: fetchUserData // provide this function in context so that it can be called elsewhere
};
return (
<UserContext.Provider value={contextValue}>{children}</UserContext.Provider>
);
};
字符串
下面是Home.js
:
const { refreshUserData } = useUserContext();
useEffect(() => {
refreshUserData(); // first attempt
}, [theme]);
const handleLogin = (e) => {
e.preventDefault();
let dataLogin = {
'email': email,
'password': password
};
JSON.stringify(dataLogin);
ApiClient.post('/login', dataLogin)
.then(resp => {
refreshUserData();
history.push('/gallery'); // second attempt
}).catch(error => {
console.log(error);
});
};
型
下面是App.js
:
import { UserProvider } from '../utilities/UserContext';
const App = () => {
return (
<Router>
<Switch>
<Route exact path="/" component={Home} />
<ProtectedRoute path="/gallery" component={Grid} />
<Route path="/support" component={Support} />
<Route path='/faq' component={FaqComp} />
</Switch>
</Router>
);
}
const container = document.getElementById('example');
const root = createRoot(container);
root.render(<UserProvider><App/></UserProvider>);
型
2条答案
按热度按时间biswetbf1#
将
headers
的声明移到fetchUserData
中,这样在localStorage
中设置token
将影响下一次提取。nkoocmlb2#
使用redux是一种更简洁的方式来存储所有组件的全局数据,你只能使用useSelector来访问这个全局数据,你可以使用chrome存储来持久化用户信息
要回复您的问题,请尝试使用上下文。消费者
字符串
您的UserProvider执行过多不必要的请求
fetchUserData在第一次呈现时被调用,即使用户没有登录
每次用户更改主题时,都会调用refreshUserData,并为未更改的数据(userId和name)调用http请求