[英]API request is failing using redux-saga in react-app
I want to load products in home page.我想在主页加载产品。 I decided to implement using
redux-saga
to take care of side effect.我决定使用
redux-saga
来解决副作用。 API call is failing in redux saga. API 调用在 redux 传奇中失败。 Here is code.
这是代码。 Can you please tell me what going wrong?
你能告诉我出了什么问题吗?
Api.js Api.js
export const getProducts = async (sort, order, page) => {
return await axios.post(`${process.env.REACT_APP_API}/products`, {
sort,
order,
page,
});
};
porduct.saga.js产品传奇.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 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 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;
Here is backend code to list all products on home这是列出家庭所有产品的后端代码
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);
}
};
When you call getProducts
function in your saga, you should set the args after the function as params.当您在 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));
}
}
Update更新
If you want to pass prop to saga如果你想将 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));
}
}
Something not working for me when i try to access props in saga file.当我尝试访问 saga 文件中的道具时,有些东西对我不起作用。
This is my saga product file.这是我的传奇产品文件。
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)]);
}
reducer.js减速器.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;
componenet file组件文件
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;
action.js动作.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,
});
I am new to this redux-saga.我是这个 redux-saga 的新手。 So, that's the reason i facing these small issue.
所以,这就是我面临这些小问题的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.