Ankush Dogra
Ankush Dogra

Reputation: 235

REACT/REDUX Action not getting dispatched

What I am tying to do is when the user clicks on sign in button my action gets dispatch with email and password. But, my action is not getting dispatched. Like when I checked my redux-dev-tools it is not showing anything: enter image description here

There are no error message in console. I checked other answer's but nothing helped.

Here is the source code:

LoginScreen.js

import React, { useState, useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import ErrorMessage from "../../components/ErrorMessage/ErrorMessage";
import Loader from "../../components/Loader/Loader";
import { login } from "../../redux/actions/userActions";
import "./LoginScreen.scss";

const LoginScreen = ({ location, history }) => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

  const dispatch = useDispatch();
  const userLogin = useSelector((state) => state.userLogin);
  const { loading, error, userInfo } = userLogin;

  const redirect = location.search ? location.search.split("=")[1] : "/";

  useEffect(() => {
    if (userInfo) {
      history.push(redirect);
    }
  }, [history, userInfo, redirect]);

  const submitHandler = (e) => {
    e.preventDefault();
    dispatch(login(email, password));
  };

  return (
    <>
      <div className="login-container">
        <div className="login-form">
          <h1>Login</h1>
          {loading ? (
            <Loader />
          ) : error ? (
            <ErrorMessage error={error} />
          ) : (
            <form onSubmit={submitHandler}>
              <div className="login-form-items">
                <input
                  className="login-input"
                  type="email"
                  placeholder="Email address"
                  value={email}
                  onChange={(e) => setEmail(e.target.value)}
                />
                <input
                  className="login-input"
                  type="password"
                  placeholder="Password"
                  value={password}
                  onChange={(e) => setPassword(e.target.value)}
                />
                <button type="submit" value="submit">
                  Login
                </button>

                <h4>OR</h4>

                <div className="login-form-social">
                  <button className="social">
                    <img
                      className="googleLogo"
                      src="/logo/google.svg"
                      alt="G"
                    />{" "}
                    Login with Google
                  </button>
                  <button className="social social-github">
                    <img
                      className="githubLogo"
                      src="/logo/github.svg"
                      alt="GH"
                    />{" "}
                    Login with GitHub
                  </button>
                </div>
              </div>
            </form>
          )}
        </div>
      </div>
    </>
  );
};

export default LoginScreen;

userAction.js

import axios from "axios";
import {
  USER_LOGIN_FAIL,
  USER_LOGIN_REQUEST,
  USER_LOGIN_SUCCESS,
} from "../constants/userConstants";

export const login = () => (email, password) => async (dispatch) => {
  try {
    dispatch({
      type: USER_LOGIN_REQUEST,
    });

    const config = {
      headers: {
        "Content-Type": "appllication/json",
      },
    };

    const { data } = await axios.post(
      "/api/users/login",
      { email, password },
      config
    );

    dispatch({
      type: USER_LOGIN_SUCCESS,
      payload: data,
    });

    localStorage.setItem("userInfo", JSON.stringify(data));
  } catch (error) {
    dispatch({
      type: USER_LOGIN_FAIL,
      payload:
        error.response && error.response.data.message
          ? error.response.data.message
          : error.message,
    });
  }
};

userReducer.js

import {
  USER_LOGIN_FAIL,
  USER_LOGIN_REQUEST,
  USER_LOGIN_SUCCESS,
  USER_LOGOUT,
} from "../constants/userConstants";

export const userLoginReducer = (state = {}, action) => {
  switch (action.type) {
    case USER_LOGIN_REQUEST:
      return { loading: true };
    case USER_LOGIN_SUCCESS:
      return { loading: false, userInfo: action.payload };
    case USER_LOGIN_FAIL:
      return { loading: false, error: action.payload };
    case USER_LOGOUT:
      return {};
    default:
      return state;
  }
};

store.js

import { createStore, combineReducers, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import { composeWithDevTools } from "redux-devtools-extension";

// reducers
import { userLoginReducer } from "./reducers/userReducers";

const reducer = combineReducers({
  userLogin: userLoginReducer,
});

const userInfoFromStorage = localStorage.getItem("userInfo")
  ? JSON.parse(localStorage.getItem("userInfo"))
  : null;

const initialState = {
  userLogin: { userInfo: userInfoFromStorage },
};
const middleware = [thunk];

const store = createStore(
  reducer,
  initialState,
  composeWithDevTools(applyMiddleware(...middleware))
);

export default store;

Upvotes: 1

Views: 815

Answers (2)

Haseeb Anwar
Haseeb Anwar

Reputation: 2918

You've defined your action wrong. With redux-thunk you define your actions like this:

export const login = (email, password) => async (dispatch) => {
  // your action code
};

// The above code is equivalent to
export const login = (email, password) => {
  return async (dispatch) => {
    // your action code
  }
}

Not like this:

export const login = () => (email, password) => async (dispatch) => {
  // your action code
};

// The above code is equivalent to
export const login = () => {
  return (email, password) => {
    return async (dispatch) => { // this is wrong

    }
  }
}

So your action is returning a function which then returns another function.

Upvotes: 3

Safa
Safa

Reputation: 74

The way you use it caught my attention. Out of general use. Generally, api operations are done with packages such as saga or thunk. Action is only used as a hyperlink. I suggest you review the article below. I think this build will solve your problem.

https://blog.devgenius.io/reactjs-simple-understanding-redux-with-redux-saga-f635e273e24a

Upvotes: 0

Related Questions