簡體   English   中英

API 請求在 react-app 中使用 redux-saga 失敗

[英]API request is failing using redux-saga in react-app

我想在主頁加載產品。 我決定使用redux-saga來解決副作用。 API 調用在 redux 傳奇中失敗。 這是代碼。 你能告訴我出了什么問題嗎?

Api.js

export const getProducts = async (sort, order, page) => {
  return await axios.post(`${process.env.REACT_APP_API}/products`, {
    sort,
    order,
    page,
  });
};

產品傳奇.js

import { takeEvery, call, put, all } from "redux-saga/effects";

import ProductActionTypes from "./product.types";

import {
  loadLatestArrivalProductSuccess,
  loadLatestArrivalProductFail,
} from "./product.actions";

import { getProducts } from "./Api";

export function* fetchLatestArrivalProducts() {
  try {
    const response = yield call(getProducts("createdAt", "desc", 1));
     // it's failing inside try
    yield put(loadLatestArrivalProductSuccess(response.data));
  } catch (error) {
    yield put(loadLatestArrivalProductFail(error));
  }
}

export function* fetchLatestArrivalProductsStart() {
  yield takeEvery(
    ProductActionTypes.LOAD_LATEST_ARRIVAL_PRODUCT_START,
    fetchLatestArrivalProducts
  );
}

export function* productSagas() {
  yield all([call(fetchLatestArrivalProductsStart)]);
}

product.reducer.js

import ProductActionTypes from "./product.types";

const INITIAL_STATE = {
  products: [],
  loading: false,
  page: 1,
  errorMessage: undefined,
};

const productReducer = (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case ProductActionTypes.LOAD_LATEST_ARRIVAL_PRODUCT_START:
      return {
        ...state,
        loading: true,
      };
    case ProductActionTypes.LOAD_LATEST_ARRIVAL_PRODUCT_SUCCESS:
      return {
        ...state,
        loading: false,
        products: action.payload,
      };
    case ProductActionTypes.LOAD_LATEST_ARRIVAL_PRODUCT_FAIL:
      return {
        ...state,
        loading: false,
        errorMessage: action.payload,
      };

    default:
      return state;
  }
};

export default productReducer;

product.type.js

const ProductActionTypes = {
  LOAD_LATEST_ARRIVAL_PRODUCT_START: "LOAD_LATEST_ARRIVAL_PRODUCT_START",
  LOAD_LATEST_ARRIVAL_PRODUCT_SUCCESS: "LOAD_LATEST_ARRIVAL_PRODUCT_SUCCESS",
  LOAD_LATEST_ARRIVAL_PRODUCT_FAIL: "LOAD_LATEST_ARRIVAL_PRODUCT_FAIL",
  LATEST_ARRIVAL_PRODUCT_COUNT: "LATEST_ARRIVAL_PRODUCT_COUNT",
};

export default ProductActionTypes;

這是列出家庭所有產品的后端代碼

 exports.list = async (req, res) => {

  try {
    const { sort, order, page } = req.body;
    const currentPage = page || 1;
    const perPage = 3;

    const products = await Product.find({})
      .skip((currentPage - 1) * perPage)
      .populate("category")
      .populate("subs")
      .sort([[sort, order]])
      .limit(perPage)
      .exec();

    res.json(products);
  } catch (err) {
    console.log(err);
  }
};

當您在 saga 中調用getProducts function 時,您應該將 function 之后的參數設置為參數。

export function* fetchLatestArrivalProducts() {
  try {
    const response = yield call(getProducts, "createdAt", "desc", 1);
     // it's failing inside try
    yield put(loadLatestArrivalProductSuccess(response.data));
  } catch (error) {
    yield put(loadLatestArrivalProductFail(error));
  }
}

更新

如果你想將 prop 傳遞給 saga

export function* fetchLatestArrivalProducts(action) {
  try {
    const response = yield call(getProducts, "createdAt", "desc", action.page);
     // it's failing inside try
    yield put(loadLatestArrivalProductSuccess(response.data));
  } catch (error) {
    yield put(loadLatestArrivalProductFail(error));
  }
}

當我嘗試訪問 saga 文件中的道具時,有些東西對我不起作用。

這是我的傳奇產品文件。

import { takeEvery, call, put, all } from "redux-saga/effects";

import ProductActionTypes from "./product.types";

import {
  loadLatestArrivalProductSuccess,
  loadLatestArrivalProductFail,
  getHomeProductsCount,
  setPage,
} from "./product.actions";

import { useSelector } from "react-redux";

import { getProducts, getProductsCount } from "../../actions/product";

export function* fetchLatestArrivalProducts(action) {
  try {
    const response = yield call(
      getProducts,
      "createdAt",
      "desc",
      action.pageNo
    );
    const countResponse = yield call(getProductsCount, "");
    yield put(loadLatestArrivalProductSuccess(response.data));
    yield put(getHomeProductsCount(countResponse.data));
  } catch (error) {
    yield put(loadLatestArrivalProductFail(error));
  }
}

export function* fetchLatestArrivalProductsStart() {
  yield takeEvery(
    ProductActionTypes.LOAD_LATEST_ARRIVAL_PRODUCT_START,
    fetchLatestArrivalProducts
  );
}

export function* productSagas() {
  yield all([call(fetchLatestArrivalProductsStart)]);
}

減速器.js

import ProductActionTypes from "./product.types";

const INITIAL_STATE = {
  products: [],
  loading: false,
  pageNo: 1,
  errorMessage: undefined,
  productsCount: 0,
};

const productReducer = (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case ProductActionTypes.LOAD_LATEST_ARRIVAL_PRODUCT_START:
      return {
        ...state,
        loading: true,
      };
    case ProductActionTypes.LOAD_LATEST_ARRIVAL_PRODUCT_SUCCESS:
      return {
        ...state,
        loading: false,
        products: action.payload,
      };
    case ProductActionTypes.LOAD_LATEST_ARRIVAL_PRODUCT_FAIL:
      return {
        ...state,
        loading: false,
        errorMessage: action.payload,
      };
    case ProductActionTypes.GET_HOME_PRODUCT_COUNT:
      return {
        ...state,
        productsCount: action.payload,
      };
    case ProductActionTypes.SET_PAGE:
      return {
        ...state,
        pageNo: action.payload,
      };
    default:
      return state;
  }
};

export default productReducer;

組件文件

import React, { useState, useEffect } from "react";
import { getProducts, getProductsCount } from "../../actions/product";
import ProductCard from "../cards/ProductCard";
import LoadingCard from "../cards/LoadingCard";
import { Pagination } from "antd";
import {
  loadLatestArrivalProductStart,
  setPage,
} from "../../redux/products/product.actions";
import { useDispatch, useSelector } from "react-redux";

const NewArrivals = () => {
  const { products, pageNo, loading, productsCount } = useSelector((state) => ({
    ...state.products,
  }));

  const dispatch = useDispatch();


  useEffect(() => {
    dispatch(loadLatestArrivalProductStart(pageNo));
  }, [pageNo]);

  return (
    <>
      <div className="container">
        {loading ? (
          <LoadingCard count={3} />
        ) : (
          <div className="row">
            {products.map((product) => (
              <div key={product._id} className="col-md-4">
                <ProductCard product={product} />
              </div>
            ))}
          </div>
        )}
      </div>
      <div className="row">
        <nav className="col-md-4 offset-md-4 text-center pt-5 p3">
          <Pagination
            current={pageNo}
            total={(productsCount / 3) * 10}
            onChange={(value) => dispatch(setPage(value))}
          />
        </nav>
      </div>
    </>
  );
};

export default NewArrivals;

動作.js

import ProductActionTypes from "./product.types";

export const loadLatestArrivalProductStart = () => ({
  type: ProductActionTypes.LOAD_LATEST_ARRIVAL_PRODUCT_START,
});

export const loadLatestArrivalProductSuccess = (products) => ({
  type: ProductActionTypes.LOAD_LATEST_ARRIVAL_PRODUCT_SUCCESS,
  payload: products,
});

export const loadLatestArrivalProductFail = (errorMsg) => ({
  type: ProductActionTypes.LOAD_LATEST_ARRIVAL_PRODUCT_FAIL,
  payload: errorMsg,
});

export const getHomeProductsCount = (count) => ({
  type: ProductActionTypes.GET_HOME_PRODUCT_COUNT,
  payload: count,
});

export const setPage = (page) => ({
  type: ProductActionTypes.SET_PAGE,
  payload: page,
});

我是這個 redux-saga 的新手。 所以,這就是我面臨這些小問題的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM