6
votes

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?

2

2 Answers

3
votes

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));
        }
      }  
};
2
votes

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);