I am trying to get a simple react-redux app to work and I am running into a weird error that I can't figure out. I am trying to simply set my current user's first name and handle the store and one set function works and the other doesn't.
setCurrentUserFirstName - works setCurrentUserHandle - doesn't
import React, { Component } from 'react'; import { Link } from 'react-router'; import { connect } from 'react-redux'; import store from '../../store'; var Utilities = require('../../../common/commonutilities.js'); var RestClient = require('../../../common/restClient.js'); //actions import { setCurrentUserHandle, setCurrentUserFirstName } from '../../actions/userActions'; class Header extends Component { constructor(props) { super(props); this.state = {}; RestClient.api.fetchGet('/getcurrentuser', (response) => { if(response.success) { this.setState({ isAuthenticated: true, currentUser: response.currentUser }); store.dispatch({ type: 'USER_DID_LOGIN', userLoggedIn: true }); //works fine this.props.setCurrentUserFirstName(response.currentUser.firstName); //doesn't work and throws the error: "TypeError: _this.props.setCurrentUserHandle is not a function" this.props.setCurrentUserHandle(response.currentUser.handle); } }, (err) => { console.log(err); }); } render() { return ( {this.props.user.currentUserFirstName}, {this.props.user.currentUserHandle} ); } } const mapStateToProps = function(store) { return { //user properties user: store.userState }; }; const mapDispatchToProps = (dispatch) => { return{ setCurrentUserFirstName: (currentUserFirstName) =>{ dispatch( setCurrentUserFirstName(currentUserFirstName)); } } return{ setCurrentUserHandle: (currentUserHandle) =>{ dispatch( setCurrentUserHandle(currentUserHandle)); } } }; //connect it all export default connect(mapStateToProps, mapDispatchToProps)(Header);
I have them as actions in the userActions.js file
export function setCurrentUserFirstName(currentUserFirstName){ return{ type: 'SET_CURRENT_USER_FIRST_NAME', payload: currentUserFirstName }; } export function setCurrentUserHandle(currentUserHandle){ return{ type: 'SET_CURRENT_USER_HANDLE', payload: currentUserHandle }; }
And in the reducer
const initialUserState = { user: {}, currentUserFirstName:[], currentUserHandle:[] }; // The User reducer const userReducer = (state = initialUserState, action) => { //using newState object to be immutable let newState = state; switch (action.type) { case 'SET_CURRENT_USER_FIRST_NAME': newState = { ...state, currentUserFirstName: action.payload }; break; case 'SET_CURRENT_USER_HANDLE': newState = { ...state, currentUserHandle: action.payload }; break; break; default: break; } return newState; }; export default userReducer;
What do I have incorrect?
You have 2 return statements in your mapDispatchToProps
- the second one will never be reached. You can return a single object as follows:
const mapDispatchToProps = (dispatch) => {
return{
setCurrentUserFirstName: (currentUserFirstName) =>{
dispatch( setCurrentUserFirstName(currentUserFirstName));
},
setCurrentUserHandle: (currentUserHandle) =>{
dispatch( setCurrentUserHandle(currentUserHandle));
}
}
};
In addition to Tony's correct answer, I highly encourage that you use the "object shorthand" form of mapDispatch
instead. You can pass an object full of action creators as the second argument to connect()
, instead of an actual mapDispatch
function. In your case, it'd look like:
import { setCurrentUserHandle, setCurrentUserFirstName } from '../../actions/userActions';
const actionCreators = { setCurrentUserHandle, setCurrentUserFirstName };
class Header extends Component {}
export default connect(mapStateToProps, actionCreators)(Header);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With