简体   繁体   English

REACT/REDUX 动作没有被分派

[英]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.我要做的是当用户单击登录按钮时,我的操作会使用 email 和密码发送。 But, my action is not getting dispatched.但是,我的行动没有被派出。 Like when I checked my redux-dev-tools it is not showing anything:就像我检查我的 redux-dev-tools 时一样,它没有显示任何内容: 在此处输入图像描述

There are no error message in console.控制台中没有错误消息。 I checked other answer's but nothing helped.我检查了其他答案,但没有任何帮助。

Here is the source code:这是源代码:

LoginScreen.js登录屏幕.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 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 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 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;

You've defined your action wrong.你错误地定义了你的行为。 With redux-thunk you define your actions like this:使用redux-thunk ,您可以像这样定义您的操作:

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.所以你的动作是返回一个 function,然后返回另一个 function。

The way you use it caught my attention.你使用它的方式引起了我的注意。 Out of general use.超出一般用途。 Generally, api operations are done with packages such as saga or thunk.通常,api 操作是通过 saga 或 thunk 等包完成的。 Action is only used as a hyperlink. Action 仅用作超链接。 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 https://blog.devgenius.io/reactjs-simple-understanding-redux-with-redux-saga-f635e273e24a

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM