React Class继承场景下Dashboard组件componentDidMount无法读取props.user问题
问题原因
- 生命周期执行时序问题:React组件挂载阶段的生命周期执行顺序为子组件componentDidMount先触发,父组件componentDidMount后触发。你的高阶组件
ComponentBaseDashboard是Dashboard的父级组件,Dashboard的componentDidMount执行时,高阶组件的componentDidMount还未运行,getViewUser请求甚至都还没有发起,自然读取不到用户数据。 - 异步请求延迟问题:
getViewUser是异步后端请求,就算请求提前发起,数据返回后更新redux状态也需要时间,赶不上Dashboard首次挂载阶段的读取操作,此时state.auth.user还是初始的undefined,读取属性就会抛出类型错误。 - 权限判断逻辑错误:高阶组件
componentDidMount中刚发起getViewUser请求就立刻判断authorized状态,此时接口还未返回,redux存储的authorized还是初始的false,会直接触发跳转,即使用户后续验证成功也无法正常进入页面。
修复步骤
1. 调整Redux初始状态
给auth模块的user设置初始空对象,避免未赋值时读取属性报错:
// auth reducer 初始值配置 const initialState = { authorized: false, user: {}, // 将原来的undefined改为空对象 loadingUser: false // 新增用户信息加载状态,用于控制渲染时机 } // 同步更新getViewUser对应的action处理逻辑: // - getViewUser请求发起时,设置 loadingUser: true // - getViewUser请求成功/失败时,设置 loadingUser: false,同时更新authorized和user的值
2. 修正高阶组件逻辑
调整高阶组件的渲染和判断逻辑,等用户信息加载完成后再渲染子组件,避免提前触发Dashboard的挂载逻辑:
// componente/index.js 高阶组件修改 const baseDashboard = Component => { class ComponentBaseDashboard extends React.Component { componentDidMount() { const { getViewUser } = this.props; getViewUser(); } componentDidUpdate() { const { authorized, loadingUser, history } = this.props; // 仅在加载完成后判断权限,未登录则跳转 if (!loadingUser && !authorized) { return history.replace("/"); } } render() { const { loadingUser } = this.props; // 加载中渲染占位符,不渲染子组件 if (loadingUser) return <div>用户信息加载中...</div> return ( <BaseDashboard> <Component {...this.props} /> </BaseDashboard> ); } } const mapStateToProps = state => ({ authorized: state.auth.authorized, user: state.auth.user, loadingUser: state.auth.loadingUser // 引入加载状态 }); return connect(mapStateToProps, actions)(ComponentBaseDashboard); }
3. 调整Dashboard数据读取逻辑
如果没有特殊需求,不需要将props的user冗余存储到组件state中,直接读取props即可;如果确实需要本地存储,监听props变化更新即可:
// pages/Dashboard.js 修改 // 不需要存储到state的场景,直接在render中用可选链读取 render() { return <div>当前登录用户:{this.props.user?.name || '暂无信息'}</div> } // 确实需要存储到state的场景 componentDidMount() { const { user } = this.props; this.setState({ user: user || {} }) } componentDidUpdate(prevProps) { // 监听user变化,同步更新本地state if (prevProps.user !== this.props.user) { this.setState({ user: this.props.user }) } }
内容的提问来源于stack exchange,提问作者Agro SEEN
相关产品推荐
相关产品推荐

