React中Redux登录跳转首页后auth.user首次未加载,如何只触发一次逻辑?
问题根因
- Home组件首次挂载时,Redux中的用户信息还未完成异步更新,
componentDidMount仅在组件挂载完成时触发1次,此时this.props.auth.user为假值,因此逻辑不触发 - 切换其他页面再返回Home时,组件会重新挂载,此时Redux中用户信息已加载完成,因此
componentDidMount内的逻辑可以正常执行 - 直接替换为
componentDidUpdate会出现多次执行问题,是因为该生命周期会在组件每次props/state更新后都触发,缺少执行限制就会重复运行
解决方案
方案1:类组件新增执行标记 + 双生命周期校验
给类组件新增执行标记,同时在componentDidMount和componentDidUpdate中做条件判断,保证逻辑仅执行一次:
class Home extends Component { constructor(props) { super(props); this.state = { unread:0, } // 新增执行标记,防止逻辑重复运行 this.hasUserLogicExecuted = false; } componentDidMount() { // 挂载时如果已存在用户信息,直接执行逻辑 if(this.props.auth.user && !this.hasUserLogicExecuted) { console.log('hello'); this.hasUserLogicExecuted = true; } } componentDidUpdate(prevProps) { // 同时满足三个条件才执行:1. 上一轮props无用户信息 2. 当前props有用户信息 3. 逻辑未执行过 if(!prevProps.auth.user && this.props.auth.user && !this.hasUserLogicExecuted) { console.log('hello'); this.hasUserLogicExecuted = true; } } render() { return( <div> // 原有业务代码 </div> ) } } const mapStateToProps = state => ({ auth: state.auth }); export default connect(mapStateToProps, { })(Home);
方案2:函数组件 + Hooks实现(React 16.8+支持,代码更简洁)
如果项目支持Hooks,重构为函数组件后用useRef存储执行标记,配合useEffect监听用户信息变化:
import { useEffect, useRef } from 'react'; import { connect } from 'react-redux'; const Home = ({ auth }) => { const hasExecuted = useRef(false); useEffect(() => { if(auth.user && !hasExecuted.current) { console.log('hello'); hasExecuted.current = true; } }, [auth.user]); // 仅监听auth.user的变化,减少无效触发 return <div> // 原有业务代码 </div> } const mapStateToProps = state => ({ auth: state.auth }); export default connect(mapStateToProps, { })(Home);
注意事项
- 原代码中
console.log('hello)缺少闭合单引号,实际运行需要修正 - 如果存在用户退出后重新登录需要重新触发该逻辑的场景,在监听到用户登出操作时将执行标记重置为
false即可
内容的提问来源于stack exchange,提问作者user16137336
相关产品推荐
相关产品推荐

