Reputation: 89
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;
Upvotes: 6
Views: 6112
Reputation: 31024
You are passing loginForm
as a store to the connected components via your rootReducer
:
const rootReducer = combineReducers({
loginForm: emailReducer
});
So inside mapstateToProps
you could do:
const mapStateToProps = (state) => {
return {
isLoginPending: state.loginForm.isLoginPending,
isLoginSuccess: state.loginForm.isLoginSuccess,
isloginError: state.loginForm.isloginError
}
}
Upvotes: 0
Reputation: 12796
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
}
}
Upvotes: 11