簡體   English   中英

REACT/REDUX 動作沒有被分派

[英]REACT/REDUX Action not getting dispatched

我要做的是當用戶單擊登錄按鈕時,我的操作會使用 email 和密碼發送。 但是,我的行動沒有被派出。 就像我檢查我的 redux-dev-tools 時一樣,它沒有顯示任何內容: 在此處輸入圖像描述

控制台中沒有錯誤消息。 我檢查了其他答案,但沒有任何幫助。

這是源代碼:

登錄屏幕.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;

你錯誤地定義了你的行為。 使用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
  }
}

不像這樣:

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

    }
  }
}

所以你的動作是返回一個 function,然后返回另一個 function。

你使用它的方式引起了我的注意。 超出一般用途。 通常,api 操作是通過 saga 或 thunk 等包完成的。 Action 僅用作超鏈接。 我建議你查看下面的文章。 我認為這個構建將解決您的問題。

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