Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redux state props value is undefined

Hey everyone so I am in the works of creating a simulation of a user logging in. I am using redux logger and my state values that is logged is always the value I want to see however, when I am console.log(this.props)

I always get back undefined. My reducer has a state values that I have defined and have passed in as defaults. I am not sure why I am getting back undefined and just can't figure it out. Here is my code. Any help would be much appreciated I need to access these values but having it undefined does not work out.

I am going to condense down the boiler plate stuff like import statements etc. Also once again for context. All I am trying to do is inside of my component be able to access my state values that are defined inside of my reducer. For example, one of them is isLoginPending. When I am console.logging this.props.isLoginPending I would hope to either get the default value or the new Object.assigned value and not undefined. That is my ideal goal is to get a value inside of my component that is not undefined.

Here is my component

render() {
        let {email, password} = this.state;
        console.log("PROPS*****" + this.props.isLoginPending);
        return (
            <div className="form-wrapper" >
                <form onSubmit={this.submit} name="login-form">
                    <label htmlFor="login-form">Email</label>
                    <input onChange={this.changedEmail} type="email" />
                    <br />
                    <label htmlFor="login-form"> Password </label>
                    <input onChange={this.changedPassword} type="password" />
                    <button type="submit">Login </button>

                </form>
            </div>
        )
    }
}

const mapStateToProps = (state) => {
    return {
       isLoginPending: state.isLoginPending,
       isLoginSuccess: state.isLoginSuccess,
       isloginError: state.isloginError
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        login: (email, password) => dispatch(login(email ,password))
    };
}


export default connect(mapStateToProps, mapDispatchToProps)(LoginForm);

Reducer

 export default function (state = {
        isLoginPending: false,
        isLoginSuccess: false,
        isLoginError: null
    }, action)
     {
        switch(action.type) {
            case constants.LOGIN_SUCCESS:
            console.log("state" + state.isLoginPending);
            return Object.assign({}, state, {isLoginSuccess: action.isLoginSuccess})

            case constants.LOGIN_PENDING:
            return Object.assign({}, state, {isLoginPending: action.isLoginPending})

            case constants.LOGIN_ERROR:

            return Object.assign({}, state, {isLoginError: action.isLoginError})

            default: 
            return state
        }
    }

Actions

export const login = (email, password) => {
    return dispatch => {
        dispatch(loginPending(true));
        dispatch(loginSuccess(false));
        dispatch(loginError(null));

    sendLoginRequest(email, password, error => {
        dispatch(loginPending(false));
        if(!error) {
            dispatch(loginSuccess(true));
        } else {
            dispatch(loginError(error));
        }
    });
    }
}

const sendLoginRequest = (email, password, callback) => {
    setTimeout(() => {
        if(email === '[email protected]' && password === 'password') {
            return callback(null);
        } 

        else {
            return callback(new Error("invalid email or password"));
        }
    }, 1000)
}

** edit **

const createStoreWithMiddleware = applyMiddleware(thunk, logger)(createStore);

ReactDOM.render(
  <Provider store={createStoreWithMiddleware(reducers)}>
    <App />
  </Provider>

root reducer that is passed into store

const rootReducer = combineReducers({
  loginForm: emailReducer
});

export default rootReducer;
like image 629
PeternDev Avatar asked Nov 29 '17 07:11

PeternDev


People also ask

Why are my props undefined?

The "Cannot read property 'props' of undefined" error occurs when a class method is called without having the correct context bound to the this keyword. To solve the error, define the class method as an arrow function or use the bind method in the class's constructor method.

Why Redux state is undefined?

When Redux initializes it dispatches a "dummy" action to fill the state. So your counter reducer was called with state equal to undefined . This is exactly the case that "activates" the default argument. Therefore, state is now 0 as per the default state value ( state = 0 ).

When to use mapStateToProps?

As the first argument passed in to connect , mapStateToProps is used for selecting the part of the data from the store that the connected component needs. It's frequently referred to as just mapState for short. It is called every time the store state changes.

What is ownProps in Redux?

ownProps are the attributes that are passed when the component is used. In plain React these would be just called props.


1 Answers

The problem is your mapStateToProps object, namely, you are expecting the flags to be on the rootstate

const mapStateToProps = (state) => {
    return {
       isLoginPending: state.isLoginPending,
       isLoginSuccess: state.isLoginSuccess,
       isloginError: state.isloginError
    }
}

However, when we see your root reducer, you have a multilevel state that adds these flags inside the state.loginForm

const rootReducer = combineReducers({
  loginForm: emailReducer
});

So changing your mapStateToProps like this should do

const mapStateToProps = (state) => {
    return {
       isLoginPending: state.loginForm.isLoginPending,
       isLoginSuccess: state.loginForm.isLoginSuccess,
       isloginError: state.loginForm.isloginError
    }
}
like image 153
Icepickle Avatar answered Sep 21 '22 10:09

Icepickle