Redux mapDispatchToProps报错:setCurrentUserHandle不是函数
你遇到的核心问题出在mapDispatchToProps函数里,同时还有几个次要问题需要一并修正,我来逐个拆解:
1. 致命错误:mapDispatchToProps的返回值逻辑错误
你在mapDispatchToProps里写了两个独立的return语句——第一个return已经把包含setCurrentUserFirstName的对象返回了,第二个return根本不会被执行,这就导致setCurrentUserHandle永远不会被注入到组件的props中,自然会抛出“不是函数”的错误。
错误代码片段:
const mapDispatchToProps = (dispatch) => { return{ setCurrentUserFirstName: (currentUserFirstName) =>{ dispatch( setCurrentUserFirstName(currentUserFirstName)); } } // 下面这段代码永远不会执行! return{ setCurrentUserHandle: (currentUserHandle) =>{ dispatch( setCurrentUserHandle(currentUserHandle)); } } };
修正后的mapDispatchToProps:
把两个action creator放在同一个返回对象里即可:
const mapDispatchToProps = (dispatch) => { return { setCurrentUserFirstName: (currentUserFirstName) => { dispatch(setCurrentUserFirstName(currentUserFirstName)); }, setCurrentUserHandle: (currentUserHandle) => { dispatch(setCurrentUserHandle(currentUserHandle)); } }; };
或者用Redux提供的bindActionCreators简化写法:
import { bindActionCreators } from 'redux'; // ... const mapDispatchToProps = (dispatch) => { return bindActionCreators({ setCurrentUserFirstName, setCurrentUserHandle }, dispatch); };
2. Reducer中的冗余语法错误
你的userReducer里在SET_CURRENT_USER_HANDLE的case后面多了一个多余的break,虽然不会直接导致功能异常,但会触发语法警告,建议删掉:
case 'SET_CURRENT_USER_HANDLE': newState = { ...state, currentUserHandle: action.payload }; break; break; // 删掉这个多余的break!
3. 初始状态的类型定义不合理
你把initialUserState里的currentUserFirstName和currentUserHandle定义成了数组[],但用户的名字和handle都是字符串类型,改成空字符串更符合业务逻辑:
const initialUserState = { user: {}, currentUserFirstName: '', // 改为空字符串 currentUserHandle: '' // 改为空字符串 };
4. Header组件render方法的JSX语法错误
你的render方法直接写了{this.props.user.currentUserFirstName}, {this.props.user.currentUserHandle},不符合JSX语法规范——JSX要求必须有一个根容器元素,比如用<div>包裹:
render() { return ( <div> {this.props.user.currentUserFirstName}, {this.props.user.currentUserHandle} </div> ); }
额外优化建议:避免直接调用store.dispatch
你在组件里直接执行了store.dispatch({ type: 'USER_DID_LOGIN', userLoggedIn: true });,更好的做法是把这个操作封装成action creator,通过mapDispatchToProps注入到props中,保持组件与store的解耦:
在userActions.js中添加:
export function userDidLogin() { return { type: 'USER_DID_LOGIN', userLoggedIn: true }; }
然后在mapDispatchToProps中注入这个action,组件里就可以用this.props.userDidLogin()来触发该操作了。
把这些问题全部修复后,你的React-Redux应用应该就能正常运行了!
内容的提问来源于stack exchange,提问作者greg

