React中如何在useEffect钩子内实现重定向?react-router-dom相关问题
react-router-dom 重定向不生效问题解决
核心问题原因
useEffect内返回<Redirect>组件完全不生效:<Redirect>是声明式路由组件,只有在组件的渲染返回值中被渲染才会触发重定向逻辑,useEffect的返回值只会作为副作用清理函数执行,不会被渲染到DOM树中,因此你写的重定向逻辑从来没有触发过。- 直接通过
store.getState()取值不会触发组件重渲染:Redux store 内的状态更新时,当前组件无法感知到变化,不会重新执行逻辑,即使后续登录状态变更也不会触发重定向。
修复方案
直接将重定向逻辑放到 <Route> 的 render 回调中,同时使用 useSelector 订阅Redux中的登录状态,保证状态更新时组件自动重渲染:
import React from 'react'; import { PropTypes } from 'prop-types'; import { Route, Redirect } from 'react-router-dom'; import { useSelector } from 'react-redux'; import AuthLayout from '../pages/_layouts/auth'; import DefaultLayout from '../pages/_layouts/default'; export default function RouteWrapper({ component: Component, isPrivate, ...rest }) { // 用useSelector订阅登录状态,状态变更时自动触发组件重渲染 const signed = useSelector(state => state.auth.signed); const googleSigned = useSelector(state => state.googleAuth.googleSigned); const Layout = signed || googleSigned ? DefaultLayout : AuthLayout; return ( <Route {...rest} render={(props) => { // 私有路由+未登录:重定向到登录页 if (!signed && !googleSigned && isPrivate) { return <Redirect to="/" />; } // 公开路由+已登录:重定向到仪表盘 if ((signed || googleSigned) && !isPrivate) { return <Redirect to="/dashboard" />; } // 正常渲染页面 return ( <Layout> <Component {...props} /> </Layout> ); }} /> ); } RouteWrapper.propTypes = { isPrivate: PropTypes.bool, component: PropTypes.oneOfType([PropTypes.element, PropTypes.func]) .isRequired, }; RouteWrapper.defaultProps = { isPrivate: false, };
逻辑验证
- 未登录状态下访问
/dashboard等私有路由,会直接重定向到登录页/ - 已登录状态下访问登录页等公开路由,会直接重定向到仪表盘
/dashboard - 登录状态变更时会自动触发重定向逻辑,无需额外手动监听
内容的提问来源于stack exchange,提问作者Ruben Martins
相关产品推荐
相关产品推荐

