【发布时间】:2021-07-12 21:24:18
【问题描述】:
我正在尝试创建受保护的路线。如果用户登录与否,我有一个反应上下文返回true or false。
问题是,即使我通过了身份验证,我仍然无法访问仪表板路由(即使我已登录,它也会重定向到登录)。我认为这是因为我向我的服务器发送了一个 api 请求以检查用户是否经过身份验证,并且当时上下文值为 undefined
我试图通过在渲染路由之前检查上下文是否未定义来解决这个问题,但它仍然不起作用。
App.js
const ctx = useContext(userContext);
console.log(ctx.authed); // return true or false
return (
<div className='App'>
<Router>
<Switch>
<Route path='/' exact component={HomePage}></Route>
<Route exact path='/auth/register' component={Register}></Route>
<Route exact path='/auth/login' component={Login}></Route>
{!ctx.loading ? (
<ProtectedRoute
path='/dashboard'
isAuth={ctx.authed}
exact
component={Dashboard}
/>
) : null}
</Switch>
</Router>
</div>
);
ProtectedRoute.js
function ProtectedRoute({ isAuth, component: Component, ...rest }) {
return (
<Route
{...rest}
render={(props) => {
if (isAuth) {
return <Component />;
} else {
return (
<Redirect to={{ pathname: '/login',
state: { from: props.location } }} />
);
}
}}
/>
);
}
我的上下文看起来像:
export const userContext = createContext({});
export default function Context(props) {
const [authed, setAuthed] = useState(undefined);
const [loading, setLoading] = useState(false);
const fetchData = async () => {
setLoading(true);
await axios({
method: 'GET',
withCredentials: true,
credentials: 'include',
url: '/checkAuthentication',
}).then((res) => {
setAuthed(res.data.authenticated);
setLoading(false);
});
};
useEffect(() => {
fetchData();
}, []);
return (
<userContext.Provider value={{ loading, authed }}>
{props.children}
</userContext.Provider>
);
}
我已经坚持了一段时间,我将不胜感激。谢谢!
【问题讨论】:
-
当您在受保护的路由中 console.log
isAuth时会看到什么? -
const [loading, setLoading] = useState(false);loading 开始为 false,在触发useEffect后的未来渲染中设置为true,这可能意味着它仍然最初渲染 ProtectedRoute 并在加载用户之前进行重定向.如果您打算使用useEffect立即加载,为什么不将加载初始化为 true? -
@azium isAuth 首先记录
undefined但当 api 返回时它会更改为true -
您的
render块在更改为true时不会再次被调用吗? -
您如何导航到仪表板?你在某处有
Link组件,还是在你的登录组件中调用navigate或history.push?
标签: javascript reactjs react-router react-context