React Component doesn't read state from reducer with 'mapStateToProps'

124 views Asked by At

I am using reducer to read states and see if the user is authenticated. I can read the states from other files but only one particular file cannot read states.

below, I define mapStateToProps

const mapStateToProps = state => ({
    user: state.auth.user,
    isAuthenticated: state.auth.isAuthenticated,
});
  
export default connect(mapStateToProps)(ViewJobPage);

and here is the render method of component

render() {
        const {user, isAuthenticated} = this.props;

        if(!isAuthenticated){
            return <Redirect to='/'/>;
        }
        
        return(
            <Card
                style={{ width: 300 }}
                cover={
                <img
                    alt="example"
                    src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"
                />
                }
                actions={[
                <SettingOutlined key="setting" />,
                <EditOutlined key="edit" />,
                <EllipsisOutlined key="ellipsis" />,
                ]}
            >
                <Card.Meta
                avatar={<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />}
                //title={user.username}
                //description={"Email: " + {user.email}}
                />
            </Card>
        );
    }

EDIT: here is my reducer file called 'auth.js' it stores the states of user as an object and isAuthenticated as a boolean

First, I define the initial states, then change it and as mentioned above, I can read the states from other files so this file should be working. Also one additional detail, when I first executed the code like this, it worked on ViewPage, but when I re-ran do code with no additional changes, it stopped reading. Could it be related to maybe a mixed file path?

// frontend/src/reducers/auth.js

import {
    USER_LOADING,
    USER_LOADED,
    AUTH_ERROR,
    REGISTER_FAIL,
    REGISTER_SUCCESS,
    LOGIN_SUCCESS,
    LOGIN_FAIL,
    LOGOUT_SUCCESS,
  } from '../actions/types';
  
  const initialState = {
    isLoading: false,
    isAuthenticated: null,
    user: null,
    token: localStorage.getItem('token')
  };
  
  export default function(state = initialState, action) {
    switch (action.type) {
      case USER_LOADING:
        return {
          ...state,
          isLoading: true
        };
      case USER_LOADED:
        return {
          ...state,
          isLoading: false,
          isAuthenticated: true,
          user: action.payload
        };
      case LOGIN_SUCCESS:
        localStorage.setItem('token', action.payload.token);
        return {
          ...state,
          isLoading: false,
          isAuthenticated: true,
          ...action.payload
        };
      case AUTH_ERROR:
      case REGISTER_FAIL:
      case REGISTER_SUCCESS:
      case LOGIN_FAIL:
        localStorage.removeItem('token');
        return {
          ...state,
          isLoading: false,
          isAuthenticated: false,
          user: null,
          token: null
        };
        case LOGOUT_SUCCESS: // added
      localStorage.removeItem('token');
      return {
        ...state,
        isLoading: false,
        isAuthenticated: false,
        user: null,
        token: null
      };
      default:
        return state;
    }
  }

EDIT 2: I have used Redux Extension to view state, as suggested. The state seems to be proper.

{
  type: 'USER_LOADED',
  payload: {
    id: 1,
    username: 'david',
    email: '[email protected]',
    is_employer: true,
    is_employee: false
  }
}

Thank you for your help!

1

There are 1 answers

1
srk On

You are calling connect twice. You only need to call it once.

So instead of this:

  ViewJobPage = connect(
    mapStateToProps
  )(ViewJobPage);
export default connect(mapStateToProps)(ViewJobPage);

You should write this:

export default connect(mapStateToProps)(ViewJobPage);