React中如何从子组件调用Redux的dispatch action?
你现在遇到的核心问题是 Login组件没有和Redux Store建立连接,导致它无法通过this.props.updateUser调用dispatch方法。另外还有几处细节问题需要修正,下面一步步帮你解决:
1. 给Login组件添加Redux连接
App组件虽然通过connect关联了Redux,但Login是路由直接渲染的独立组件,不会自动继承App的Redux映射props。你需要给Login也做Redux连接:
在Login.js文件末尾添加以下代码(记得先导入connect):
import { connect } from 'react-redux'; // ... 你的Login组件代码 ... // 把dispatch方法映射到Login的props中 const mapDispatchToProps = (dispatch) => { return { updateUser: (user) => { dispatch({ type: "UPDATE_USER", payload: user }) } } }; // Login不需要读取全局状态,所以mapStateToProps传null即可 export default connect(null, mapDispatchToProps)(Login);
这样Login组件就能通过this.props.updateUser正常触发action了。
2. 修正App组件的mapStateToProps
你的Store是直接用saveUserData这个reducer创建的,所以Store的根状态就是该reducer返回的对象({ user: {} }),而非包含saveUserData属性的嵌套对象。所以App里的映射逻辑需要修改:
const mapStateToProps = (state) => { return { userData: state.user // 直接取根状态里的user,而非state.saveUserData }; };
3. 修复index.js里的subscribe回调错误
你在store.subscribe里写的console.log(state.getState())存在变量未定义问题,应该调用store.getState():
store.subscribe( () => { console.log(store.getState()); // 改为store.getState() });
4. 优化Reducer的写法(可选但推荐)
Redux要求reducer是纯函数,建议直接返回新状态对象而非修改原state,同时不要忘记添加default case:
const saveUserData = (state = { user: {} }, action) => { switch (action.type) { case "UPDATE_USER": return { ...state, user: action.payload }; // 返回新对象,不修改原state default: return state; // 必须添加,否则未匹配的action会返回undefined } };
为什么原来的方法不行?
每个需要与Redux交互的组件都需要单独通过connect(或Redux Hooks)与Store关联,App组件的映射props不会自动传递给路由渲染的子组件。完成上述修改后,Login里的this.props.updateUser(response.user)就能正常触发action,将用户数据存入全局Store了。
内容的提问来源于stack exchange,提问作者Emu

