trinny
trinny

Reputation: 232

React Hooks and Redux - trouble getting value from action creator

so I am making a small project learning about hooks, and it is a little nightmare :)

I have a login form component that calls to action creator to login, after that I want to use value that has been changed in this action, ex. isLoggedIn. I can see the value in store has been changed in chrome react dev tools, but it's not working in code. Below is the code sample.

Reducer (reducer.js):

const initialState = {
  user: {},
  isFetching: false,
  isLoggedIn: false,
  error: false
};

export default function loginReducer(state = initialState, action) {
  switch (action.type) {
    case types.LOGIN_SUCCESS:
      return {
        ...state,
        isFetching: false,
        isLoggedIn: true,
        error: false,
        user: action.user
      };
    default:
      return state;
  }
}

Action Creator (actions.js)

export function loginToApi(credentials) {
  return function(dispatch) {
        axios
          .post("https://localhost:44320/Login", {
            email: credentials.email,
            password: credentials.password
          })
          .then(response => {
            dispatch(loginSuccess(response.data));
          })
      })
  };
}

function loginSuccess(user) {
  return { type: types.LOGIN_SUCCESS, user };
}

Login form component (form.js)

import React, { useState } from "react";
import { Redirect } from "react-router-dom";
import useForm from "./useForm";
import validate from "./LoginFormValidationRules";
import { loginToApi } from "../../redux/actions/loginActions";
import { connect } from "react-redux";

export function Form({ loginToApi, isLoggedIn }) {
  // custom form hook
  const { values, errors, handleChange, handleSubmit } = useForm(
    { accountType: "1", email: "", password: "" },
    login,
    validate
  );

  const [loginFailed, setLoginFailed] = useState(false);

  function redirect() {
    if (isLoggedIn) { // I want to use those variables here
      return <Redirect to="/home" />;
    }
  }

  function login() {
    loginToApi(values);
  }

  return (
    <div>
      {redirect()}
      // form, I want to use error variable here for valdiations as well
    </div>
  );
}

function mapStateToProps(state) {
  console.log(state); // I can see change here
  return {
    user: state.user,
    isLoggedIn: state.isLoggedIn,
    error: state.error
  };
}

const mapDispatchToProps = {
  loginToApi
};

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

So I want to use in this component values like error or isLoggedIn, but I don't know how to get them. All I get is undefined.

Help appreciated.

@edit As requested my usage of Form component:

index.js:

const store = configureStore();

render(
  <ReduxProvider store={store}>
    <Router>
      <App />
    </Router>
  </ReduxProvider>,
  document.getElementById("app")
);

App.js:

function App() {
  return (
    <div>
      <Switch>
        <Route path="/login" component={LoginPage} />
      </Switch>
    </div>
  );
}

LoginPage.js:

const LoginPage = () => (
  <div>
     <LoginForm />
  </div>
);

export default LoginPage;

configureStore.js:

export default function configureStore(initialState) {
  const composeEnhancers =
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; // add support for Redux dev tools

  return createStore(
    rootReducer,
    initialState,
    composeEnhancers(applyMiddleware(thunk, reduxImmutableStateInvariant()))
  );
}

rootReducer:

const rootReducer = combineReducers({
  reducer: reducer
});

export default rootReducer;

Hope this helps you see the problem, because I still have not resolved the issue.. thanks!

Upvotes: 2

Views: 934

Answers (2)

Akram Badah
Akram Badah

Reputation: 427

I believe in your Login form component (form.js),

values in mapStateToProps function should be like this:

function mapStateToProps(state) {
  console.log(state.reducer); // I can see change here
  return {
    user: state.reducer.user,
    isLoggedIn: state.reducer.isLoggedIn,
    error: state.reducer.error
  };
}

Upvotes: 1

Shubham J.
Shubham J.

Reputation: 646

In form.js file: can you please try using this:

function redirect() {
    if (this.props.isLoggedIn || this.props.isLoggedIn.loginReducer.isLoggedIn) { 
      return <Redirect to="/home" />;
    }
  }

Upvotes: 0

Related Questions