我有4个类别anmial
,treatment
,dailyEssentials
和medical-care
在左侧有3个卡为treatment
,dailyEssentials
和medical-care
和一个下拉菜单选择animals
。
该产品得到更新完美的Animal
和treatment
类别,但dailyEssentials
和medical-care
不给所需的产品作为输出,而不是它的显示所有的产品.
网址-http://localhost:3000/search/essential/6451eafc000f972917fe38fe
6451eafc000f972917fe38fe
是每日必不可少的类别ID。
我有一个问题,treatment
卡是非常相似的dailyEssentials
和medical-care
在我的情况下treatment
是工作正常,那么为什么不dailyEssentials
和medical-care
。
这是后端
exports.showAllProducts = catchAsyncError(async (req, res, next) => {
try {
// enable search
const keyword = req.query.keyword
? {
name: {
$regex: req.query.keyword,
$options: 'i',
},
}
: {};
// enable filter by animal
const animalId = req.query.animal;
const animalFilter = animalId ? { animal: animalId } : {};
// enable filter by treatment
const treatmentId = req.query.treatment;
const treatmentFilter = treatmentId ? { treatment: treatmentId } : {};
//enable filter by essentials
const essentialId = req.query.dailyEssential;
const essentialFilter = essentialId ? {dailyEssential: essentialId}: {};
//enable filter by medical care
const medicalCareId = req.query.medicalCare;
const medicalCareFilter = medicalCareId ? {medicalCare: medicalCareId}:{};
// enable pagination
const pageSize = 4;
const page = Number(req.query.pageNumber) || 1;
// construct the filter based on the keyword and any additional filters
const filter = {
...keyword,
...animalFilter,
...treatmentFilter,
...essentialFilter,
...medicalCareFilter,
};
const count = await Product.find(filter).countDocuments();
const products = await Product.find(filter)
.skip(pageSize * (page - 1))
.limit(pageSize);
res.status(200).json({
success: true,
count,
products,
page,
pages: Math.ceil(count / pageSize),
});
} catch (error) {
next(error);
}
});
基本操作
import { DAILY_ESSENTIALS_TYPE_LOAD_FAIL, DAILY_ESSENTIALS_TYPE_LOAD_REQUEST, DAILY_ESSENTIALS_TYPE_LOAD_RESET, DAILY_ESSENTIALS_TYPE_LOAD_SUCCESS } from "../../constants/categories/dailyEssentialsConstants";
import axios from 'axios'
export const dailyEssentialsTypeLoadAction = () => async (dispatch) => {
dispatch({ type: DAILY_ESSENTIALS_TYPE_LOAD_REQUEST });
try {
const { data } = await axios.get('/api/v1/essential');
dispatch({
type: DAILY_ESSENTIALS_TYPE_LOAD_SUCCESS,
payload: data
});
} catch (error) {
dispatch({
type: DAILY_ESSENTIALS_TYPE_LOAD_FAIL,
payload: error.response.data.error
});
}
}
基本还原剂
import { DAILY_ESSENTIALS_TYPE_LOAD_FAIL, DAILY_ESSENTIALS_TYPE_LOAD_REQUEST, DAILY_ESSENTIALS_TYPE_LOAD_RESET, DAILY_ESSENTIALS_TYPE_LOAD_SUCCESS } from "../../constants/categories/dailyEssentialsConstants";
export const loadDailyEssentialTypeReducer = (state = {dailyEssentialType:[] },action)=>{
switch (action.type){
case DAILY_ESSENTIALS_TYPE_LOAD_REQUEST:
return { loading : true}
case DAILY_ESSENTIALS_TYPE_LOAD_SUCCESS:
return {
loading: false,
dailyEssentialType: action.payload.essentialT
}
case DAILY_ESSENTIALS_TYPE_LOAD_FAIL:
return {
loading: false,
error: action.payload
}
case DAILY_ESSENTIALS_TYPE_LOAD_RESET:
return {}
default:
return state;
}
}
import React, { useEffect, useState } from 'react';
import './product.css';
import { Box, Card, CardContent, Stack, Typography } from '@mui/material';
import ProductCard from './ProductCard';
import { useDispatch, useSelector } from 'react-redux';
import { getProduct } from '../../actions/productAction';
import { Link, useParams } from 'react-router-dom';
import Pagination from '@mui/material/Pagination';
import Loader from '../layout/Loader/Loader';
import SelectComponent from './SelectComponent';
import { animalTypeLoadAction } from '../../actions/categories/animalTypeAction';
import { treatmentTypeLoadAction } from '../../actions/categories/treatmentTypeAction';
import { dailyEssentialsTypeLoadAction } from '../../actions/categories/dailyEssentialTypeAction';
import { medicalCareTypeLoadAction } from '../../actions/categories/medicalCareTypeAction';
const dispatch = useDispatch();
const {error,loading,products,pages} = useSelector(state=>state.products)
const { keyword,treatment,essential,medical} = useParams()
const { treatmentType } = useSelector(state => state.treatmentTypeAll)
const { dailyEssentialType } = useSelector(state => enter image description herestate.dailyEssentialTypeAll)
const { MedicalCareType } = useSelector(state => state.medicalCareTypeAll)
const [page, setPage ] = useState(1);
const [animal, setAnimal ] = useState();
useEffect(()=>{
dispatch(getProduct(page,keyword,animal,treatment,essential,medical))
},[dispatch,page,keyword,animal,treatment,essential,medical])
useEffect(()=>{
dispatch(animalTypeLoadAction())
dispatch(treatmentTypeLoadAction())
dispatch(dailyEssentialsTypeLoadAction())
dispatch(medicalCareTypeLoadAction())
},[])
const handleChangeCategory=(e)=>{
setAnimal(e.target.value)
}
return (
<div>
{
loading ? <Loader /> : <>
<Box sx={{ bgcolor: '#fff', minHeight: '100vh' }}>
<Stack direction={{ xs: 'column', sm: 'row' }} spacing={{ xs: 1, sm: 2, md: 4 }}>
<Box sx={{ flex: 2, p: 2 }}>
<Card sx={{ minWidth: 170, mb: 3, mt: 3, p: 2 }}>
<Box sx={{ pb: 2 }}>
<Typography component="h4" sx={{ color: '#217c04', fontWeight: 700, fontFamily: 'Inter' }}>
SORT AS PER YOUR PREFERENCE
</Typography>
</Box>
<SelectComponent handleChangeCategory={handleChangeCategory} animal={animal} />
</Card>
{/* treatment category card*/}
<Card sx={{ minWidth: 150, mb: 3,mt:2, p: 2 }}>
<Box sx={{ pb: 2 }}>
<Typography component="h4" sx={{ color: '#217c04', fontWeight: 600 }}>
SORT BY TREATMENT
</Typography>
{
treatmentType && treatmentType.map((treatment) => (
<Link className='link' to={`/search/treatment/${treatment._id.toString()}`} key={treatment._id}>
<Card sx={{ minWidth: 150, mb: 1,mt:1, p: 1}}>
<CardContent>
<Typography variant="h6" color="text.primary">
{treatment.TreatmentTypeName}
</Typography>
</CardContent>
</Card>
</Link>
))
}
</Box>
</Card>
{/* daily-Essential-Card */}
<Card sx={{ minWidth: 150, mb: 3,mt:2, p: 2 }}>
<Box sx={{ pb: 2 }}>
<Typography component="h4" sx={{ color: '#217c04', fontWeight: 600 }}>
OUR DAILY ESSENTIALS
</Typography>
{
dailyEssentialType && dailyEssentialType.map((essential) => (
<Link className='link' to={`/search/essential/${essential._id.toString()}`} key={essential._id}>
<Card sx={{ minWidth: 150, mb: 1,mt:1, p: 1}}>
<CardContent>
<Typography variant="h6" color="text.primary">
{essential.essentialName}
</Typography>
</CardContent>
</Card>
</Link>
))
}
</Box>
</Card>
{/* medical-care-card */}
<Card sx={{ minWidth: 150, mb: 3,mt:2, p: 2 }}>
<Box sx={{ pb: 2 }}>
<Typography component="h4" sx={{ color: '#217c04', fontWeight: 600 }}>
SORT BY Medical
</Typography>
{
MedicalCareType && MedicalCareType.map((medical) => (
<Link className='link' to={`/search/medical/${medical._id.toString()}`} key={medical._id}>
<Card sx={{ minWidth: 150, mb: 1,mt:1, p: 1}}>
<CardContent>
<Typography variant="h6" color="text.primary">
{medical.medicalCareName}
</Typography>
</CardContent>
</Card>
</Link>
))
}
</Box>
</Card>
</Box>
{/* main card */}
{
products && products.length === 0 ? <>
<Box
sx={{
minHeight: '350px',
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
}}>
<h2>No result found!</h2>
</Box>
</> :
<>
<div className='product-main-container' style={{ display: 'flex', flexDirection: 'column' }}>
<Box sx={{ flex: 6, p: 1,mt:4 }}>
<Box sx={{ minHeight: '350px', display: 'flex', justifyContent: 'center', alignItems: 'center',flexDirection: 'column' }}>
{products.map((product) => (
<ProductCard key={product._id} product={product} />
))}
</Box>
<Stack spacing={2} >
<Pagination variant='outlined' className='pagination' page={page} count={pages === 0 ? 1 : pages} onChange={(event, value) => setPage(value)} />
</Stack>
</Box>
</div>
</>
}
</Stack>
</Box>
</>
}
</div>
);
};
export default Product;
import './App.css';
import Home from './components/Home/Home';
import Navbar from './components/Navbar/Navbar';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css'
import '../node_modules/bootstrap/dist/js/bootstrap.bundle'
import {BrowserRouter as Router, Route, Routes} from 'react-router-dom';
import Login from './components/user/Login';
import Product from './components/product/Product';
function App() {
return (
<>
<Router>
<Navbar />
<Routes>
<Route path='/' element={<Home />} />
<Route path='/login' element={<Login />} />
<Route path='/products' element={<Product />} />
{/* product categories routes */}
<Route path='/search/treatment/:treatment' element={<Product />} />
<Route path='/search/essential/:essential' element={<Product />} />
<Route path='/search/medical/:medical' element={<Product />} />
</Routes>
</Router>
</>
);
}
export default App;
productAction.js
import axios from 'axios';
import {
ALL_PRODUCT_REQUEST,
ALL_PRODUCT_SUCCESS,
ALL_PRODUCT_FAIL,
CLEAR_ERRORS
} from "../constants/productConstants"
export const getProduct = (pageNumber,keyword='',animal='',treatment='',essential='',medical='') => async (dispatch)=>
{
try{
dispatch({type:ALL_PRODUCT_REQUEST})
//let link = `/api/v1/products`;
let link = `/api/v1/products/?pageNumber=${pageNumber}&keyword=${keyword}&animal=${animal}&treatment=${treatment}&essential=${essential}&medical=${medical}`;
const {data} = await axios.get(link)
dispatch({
type:ALL_PRODUCT_SUCCESS,
payload:data,
})
}
catch(error){
dispatch({
type: ALL_PRODUCT_FAIL,
payload:error.response.data.message,
})
}
}
2条答案
按热度按时间olhwl3o21#
所以这是我的错误错误是在ProductAction.js
链接为
/api/v1/products/?pageNumber=${pageNumber}&keyword=${keyword}&animal=${animal}&treatment=${treatment}&dailyEssential=${dailyEssential}
而不是
essentials
我应该使用dailyEssential
medical
,我应该使用medicalCare
avwztpqn2#
您应该有条件地选择要分派哪个操作来调用正确/预期的后端API。为每个路由指定一个“类别”属性以传递给
Product
,这样可以更容易地选择正确的端点。示例:
从这里开始,每个动作都应该从各自的API中获取预期的数据,并更新相应的状态,要么是
products
状态,要么是它自己的状态,这些状态也需要在Product
组件中选择才能呈现。