使用Redux mapStateToProps时状态被莫名键值对包裹的问题
问题描述
我正在开发基于React Native、Firebase和Redux的应用,此前Redux使用一直正常,但今日突发无明显诱因的异常:
通过Firebase登录后,调用Redux action将用户对象存入store,对应的action和reducer代码中,Reducer的alert显示payload是符合预期的用户对象。但在某组件中通过connect和mapStateToProps获取状态时,输出的用户对象被_z、_x等随机键包裹,有时还会嵌套。临时通过user['_z']可获取正确值,但并非合理方案。
已尝试重装redux和react-redux、重建应用、重启电脑、简化reducer等操作,问题仍未解决,恳请帮助。
相关代码
登录逻辑代码
await signInWithEmailAndPassword(auth, email, pass) .then(async (userCredential) => { const user = userCredential.user; const token = await auth.currentUser?.getIdToken(); props.setUser({ id: user['uid'], email: user['email'], token: token }); props.navigation.navigate('Home'); })
Action代码
export const setUser = (payload: User) => ( { type: 'SET_USER', payload: payload } );
Reducer代码
const userReducer = async (state = INITIAL_USER_STATE, action: { type: string; payload: User; }) => { switch (action.type) { default: return state; case 'SET_USER': alert('payload: ' + JSON.stringify(action.payload)); return action.payload; } };
组件mapStateToProps代码
const mapStateToProps = (state: { user: User }) => { const { user } = state; return { user }; }; export default connect(mapStateToProps, null)(PlaidBackDrop);
解决方案
核心问题
你的Reducer被定义成了async函数——Redux的Reducer必须是同步纯函数,不能是异步函数。异步函数会返回一个Promise对象,而非直接返回状态值。当组件获取这个Promise对象时,它的内部状态会被包裹在_z、_x这类Promise实现的内部属性中,导致你看到的异常结构。
修复步骤
- 移除Reducer的async关键字
修改Reducer代码,确保它是同步纯函数:const userReducer = (state = INITIAL_USER_STATE, action: { type: string; payload: User; }) => { switch (action.type) { default: return state; case 'SET_USER': alert('payload: ' + JSON.stringify(action.payload)); return action.payload; } }; - 规范异步操作位置
所有异步逻辑(比如Firebase登录、获取Token)都要放在Action Creator或Redux中间件(如Redux Thunk)中处理,Reducer只负责同步更新状态。你的登录逻辑已经在外部处理了异步操作,Reducer完全不需要异步。 - 重新测试验证
保存修改后重启应用,组件通过mapStateToProps获取的用户对象会恢复正常结构,不再出现_z这类内部属性。
内容的提问来源于stack exchange,提问作者Marcus Edwards
相关产品推荐
相关产品推荐

