我正在尝试在正在构建的React Node.js应用中实现搜索过滤器。当用户打开页面时,应该加载所有产品,然后用户可以添加过滤器以缩小产品范围。产品加载完毕,但过滤器不起作用。
过滤器被发送到后端,但是有些东西无法正常工作。
有什么我想念的吗?这是前端代码。
const Shop = () => {
// All the states needed for this component
const [categories, setCategories] = useState([]);
const [error, setError] = useState(false);
const [limit, setLimit] = useState(6);
const [skip, setSkip] = useState(0);
const [myFilters, setMyFilters] = useState({
filters: { category: [], price: [] },
});
const [filteredResults, setFilteredResults] = useState(0);
//API url for fetching all categories
let one = process.env.REACT_APP_API_URL + "/categories";
//function to load up all categories
const init = () => {
fetch(one, {
method: "GET",
})
.then((res) => res.json())
.then((data) => {
if (data.error) {
setError(data.error);
} else {
setCategories(data);
}
})
.catch((err) => console.log(err));
};
//function to send search filters to backend
const loadFilteredResults = (newFilters) => {
getFilteredProducts(limit, skip, newFilters).then((data) => {
if (data.error) {
setError(data.error);
} else {
setFilteredResults(data);
console.log(data);
}
console.log(newFilters);
});
};
//UseEffect to load when component mounts. Fetches all categories and fetches all products
useEffect(() => {
init();
loadFilteredResults(limit, skip, myFilters.filters);
}, []);
//method for collecting values to use as filters from each checkbox user checks
const handleFilters = (filters, filterBy) => {
const newFilters = { ...myFilters };
newFilters.filters[filterBy] = filters;
if (filterBy === "price") {
let priceValues = handlePrice(filters);
newFilters.filters[filterBy] = priceValues;
}
loadFilteredResults(myFilters.filters);
setMyFilters(newFilters);
};
// Method for handling array for price radio buttons
const handlePrice = (value) => {
let data = prices;
let array = [];
for (let key in data) {
if (data[key]._id === parseInt(value)) {
array = data[key].array;
}
}
return array;
};
return (
<div className="shop-wrapper container">
<div className="row">
<div className="col-4">
<h3 className="mt-5">Filter by Category</h3>
<ul>
<Checkbox
categories={categories}
handleFilters={(filters) => handleFilters(filters, "category")}
/>
</ul>
<h3 className="mt-3">Filter by Price</h3>
<ul>
<Radio
prices={prices}
handleFilters={(filters) => handleFilters(filters, "price")}
/>
</ul>
</div>
<div className="col-8">{JSON.stringify(filteredResults)}</div>
</div>
</div>
);
};
export default Shop;
当我记录过滤器时,我看到一切正常。 API方法是
const getFilteredProducts = (skip, limit, filters) => {
const data = { skip, limit, filters };
return fetch(process.env.REACT_APP_API_URL + "/products/by/search", {
method: "POST",
headers: {
Accept: "application/json",
"Content-type": "application/json",
},
body: JSON.stringify(data),
})
.then((res) => res.json())
.catch((err) => console.log(err));
};
后端处理搜索过滤器的方法是
exports.listBySearch = (req, res) => {
let order = req.body.order ? req.body.order : "desc";
let sortBy = req.body.sortBy ? req.body.sortBy : "_id";
let limit = req.body.limit ? parseInt(req.body.limit) : 100;
let skip = parseInt(req.body.skip);
let findArgs = {};
// console.log(order, sortBy, limit, skip, req.body.filters);
// console.log("findArgs", findArgs);
for (let key in req.body.filters) {
if (req.body.filters[key].length > 0) {
if (key === "price") {
// gte - greater than price [0-10]
// lte - less than
findArgs[key] = {
$gte: req.body.filters[key][0],
$lte: req.body.filters[key][1],
};
} else {
findArgs[key] = req.body.filters[key];
}
}
}
Product.find(findArgs)
.select("-photo")
.populate("category")
.sort([[sortBy, order]])
.skip(skip)
.limit(limit)
.exec((err, data) => {
if (err) {
return res.status(400).json({
error: "Products not found",
});
}
res.json({
size: data.length,
data,
});
});
};
查询的路径也是
router.post("/products/by/search", listBySearch);
从任何人那里获得帮助都会节省生命。