React项目中登录跳转后Home组件componentDidMount函数未触发的原因及解决方法
问题原因分析
这个问题我之前也碰到过!核心原因是首次跳转至Home页面时,组件的componentDidMount执行时机早于Redux中auth.user的加载完成:
- 登录流程中,你大概率是先完成登录跳转,再异步请求加载用户信息(或者用户信息的异步请求和跳转几乎同时发生);
- Home组件挂载时,
this.props.auth.user还未被更新到Redux store中,所以if(this.props.auth.user)的条件不满足,自然不会打印'hiii'; - 当你跳转到其他页面再返回Home时,
auth.user已经存在于Redux store里了,此时组件重新挂载,componentDidMount执行时条件满足,就会正常打印。
解决方案
针对这个场景,有两种常用的解决方式,你可以根据项目组件风格选择:
方式一:类组件中添加componentDidUpdate监听props变化
componentDidMount只会在组件挂载时执行一次,我们可以通过componentDidUpdate监听auth.user的变化,当它从无到有时执行逻辑:
class Home extends Component { constructor(props) { super(props); this.state = { } } componentDidMount() { // 挂载时先检查一次 this.logWhenUserExists(); } componentDidUpdate(prevProps) { // 对比前后props,当auth.user从无到有时触发 if (!prevProps.auth.user && this.props.auth.user) { this.logWhenUserExists(); } } logWhenUserExists() { if(this.props.auth.user) { console.log('hiii'); } } render() { return <div>Home Page</div>; } } const mapStateToProps = state => ({ auth: state.auth }); export default connect(mapStateToProps, { })(Home);
方式二:转为函数组件,使用useEffect监听依赖
如果你的项目允许使用函数组件和Hooks,这种方式会更简洁,useEffect可以直接监听auth.user的变化:
import { useEffect } from 'react'; import { connect } from 'react-redux'; const Home = ({ auth }) => { useEffect(() => { if (auth.user) { console.log('hiii'); } }, [auth.user]); // 仅当auth.user变化时执行该回调 return <div>Home Page</div>; }; const mapStateToProps = state => ({ auth: state.auth }); export default connect(mapStateToProps, {})(Home);
额外提示:如果你的用户信息加载是异步请求,也可以考虑在登录成功后,等用户信息加载完成再跳转到Home页面,这样首次挂载时auth.user就已经存在,componentDidMount里的逻辑也能直接触发。比如在登录的action中,先完成用户信息请求,再调用跳转逻辑。
内容的提问来源于stack exchange,提问作者user16137336
相关产品推荐
相关产品推荐

