Redux获取用户认证数据前PrivateRoute提前渲染,如何修复?
解决PrivateRoute在Redux获取用户数据前提前渲染的问题
这个问题的核心在于你目前的PrivateRoute没有和Redux状态绑定,而是依赖一个全局的userAuth对象,而且路由判断逻辑没等用户会话数据加载完成就执行了。下面是具体的修复方案:
1. 让PrivateRoute连接Redux,直接读取状态
把PrivateRoute改成连接Redux的组件,这样它能实时获取Redux里的用户认证状态,不再依赖全局变量。同时,我们可以在PrivateRoute里处理加载状态,避免过早跳转:
import { connect } from 'react-redux'; const PrivateRoute = ({ component: Component, user, ...rest }) => ( <Route {...rest} render={(props) => { // 如果正在获取用户会话,显示加载提示(也可以返回null或自定义加载组件) if (user.isFetchingCurrentUserSession) { return <div><img src={squareLogo} className="logo-loading" alt="Loading icon" /></div>; } // 根据Redux里的真实状态判断路由跳转 return user.isLoginSuccess ? ( <Component {...props} /> ) : ( <Redirect to="/login" /> ); }}/> ); // 从Redux状态中获取需要的用户数据 const mapStateToProps = state => ({ user: state.user }); export default connect(mapStateToProps)(PrivateRoute);
2. 简化App组件的逻辑
现在PrivateRoute自己能处理加载和认证判断了,App组件里就不需要再维护全局的userAuth对象,也不用在render里手动设置它的值。修改后的App组件:
class App extends Component { componentDidMount() { // 依然在组件挂载时触发获取用户会话的动作 this.props.getCurrentUserSession(); } render() { return ( <Router> <div> <Route path="/public" component={Public} /> <PrivateRoute path="/private" component={Private} /> </div> </Router> ); } } function mapStateToProps(state) { return { user: state.user }; } function mapDispatchToProps(dispatch) { return bindActionCreators({ getCurrentUserSession }, dispatch); } export default connect(mapStateToProps, mapDispatchToProps)(App);
为什么这样能解决问题?
PrivateRoute现在直接订阅Redux的user状态,每当Redux里的isFetchingCurrentUserSession或isLoginSuccess变化时,它都会自动重新渲染,执行最新的路由判断逻辑。- 我们在
PrivateRoute里加入了加载状态判断,避免在用户会话数据还没拿到时就跳转到登录页,而是显示加载提示,直到数据加载完成。 - 移除了全局的
userAuth对象,彻底避免了状态不同步的问题——之前全局对象的更新无法触发PrivateRoute的重新渲染,现在通过Redux的连接,状态变化会自动驱动组件更新。
另外要注意:确保你的Redux初始状态里isFetchingCurrentUserSession的初始值设为true,或者在getCurrentUserSession动作触发时立刻把isFetchingCurrentUserSession设为true,这样PrivateRoute一开始就会显示加载状态,不会直接执行认证判断。
内容的提问来源于stack exchange,提问作者Skate to Eat
相关产品推荐
相关产品推荐

