React-redux中mapStateToProps返回的user在componentDidMount阶段为空如何解决
问题原因
Redux 中的 selectCurrentUser 数据是异步加载的,组件 componentDidMount 生命周期仅在首次挂载时执行一次,此时用户数据还未注入到 props 中,因此拿到的是 null。
解决方案
方案1:使用 componentDidUpdate 监听 user 变化(最适配现有代码)
在 props 中的 user 从无到有时触发数据请求,同时增加请求状态避免重复调用:
class GroupsPage extends React.Component { constructor(props){ super(props); this.state = { groups: [], isGroupsFetched: false // 新增请求状态标记 } } async fetchGroups (){ // 如果接口需要传入用户参数,直接从 this.props.user 取值即可 fetchGroupsFirebase().then((res) => { this.setState({groups:res, isGroupsFetched: true}) }) }; async componentDidMount() { // 兼容首次挂载时 user 已经加载完成的场景 if(this.props.user && !this.state.isGroupsFetched){ await this.fetchGroups(); } } async componentDidUpdate(prevProps) { // 仅在 user 从无到有、且未请求过数据时调用接口 if(this.props.user && !prevProps.user && !this.state.isGroupsFetched){ await this.fetchGroups(); } } render(){} } const mapStateToProps = createStructuredSelector({ user: selectCurrentUser }) export default connect(mapStateToProps)(GroupsPage);
方案2:上层逻辑预加载用户数据
在路由守卫、父组件等上层逻辑判断用户数据加载完成后再渲染 GroupsPage 组件,这样组件挂载时 props 已经存在 user 值,直接在 componentDidMount 调用即可,示例逻辑如下:
// 父组件/路由组件示例 {currentUser ? <GroupsPage /> : <Loading />}
方案3:迁移到函数组件使用Hook(可选优化)
如果可以重构为函数组件,使用 useEffect 依赖 user 实现监听,逻辑更简洁:
const GroupsPage = ({user}) => { const [groups, setGroups] = useState([]) useEffect(() => { if(!user) return const getGroups = async () => { const res = await fetchGroupsFirebase() setGroups(res) } getGroups() }, [user]) // user变化时自动触发校验执行 return <></> } const mapStateToProps = createStructuredSelector({ user: selectCurrentUser }) export default connect(mapStateToProps)(GroupsPage);
内容的提问来源于stack exchange,提问作者MasterWilliams
相关产品推荐
相关产品推荐

