You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于MERN栈项目,如何在React中实现商品价格筛选功能?

嘿,针对你MERN栈项目里的商品价格筛选需求,我分前后端两部分给你拆解下具体实现步骤,都是实际项目里常用的方案~

前端React实现部分

首先你需要在React组件里管理价格筛选的状态,同时处理商品数据的展示和过滤逻辑。这里分两种场景:

场景1:数据量较小(几百条以内)—— 前端直接过滤

这种情况不用麻烦后端,拿到所有商品数据后在前端用数组的filter方法处理就行:

import { useState, useEffect } from 'react';

function ProductPriceFilter() {
  // 存储所有商品原始数据
  const [allProducts, setAllProducts] = useState([]);
  // 存储筛选后的商品
  const [filteredProducts, setFilteredProducts] = useState([]);
  // 价格范围状态
  const [minPrice, setMinPrice] = useState('');
  const [maxPrice, setMaxPrice] = useState('');

  // 页面加载时先获取所有商品
  useEffect(() => {
    const fetchProducts = async () => {
      try {
        const res = await fetch('/api/products');
        const data = await res.json();
        setAllProducts(data);
        setFilteredProducts(data); // 初始显示全部
      } catch (err) {
        console.error('获取商品数据失败:', err);
      }
    };
    fetchProducts();
  }, []);

  // 实时筛选:用户输入价格时自动触发
  useEffect(() => {
    let result = [...allProducts];
    
    // 过滤最低价格
    if (minPrice) {
      result = result.filter(product => product.price >= parseFloat(minPrice));
    }
    // 过滤最高价格
    if (maxPrice) {
      result = result.filter(product => product.price <= parseFloat(maxPrice));
    }

    setFilteredProducts(result);
  }, [minPrice, maxPrice, allProducts]);

  return (
    <div className="product-filter-container">
      {/* 价格筛选控件 */}
      <div className="filter-controls">
        <input
          type="number"
          placeholder="输入最低价格"
          value={minPrice}
          onChange={(e) => setMinPrice(e.target.value)}
        />
        <span>~</span>
        <input
          type="number"
          placeholder="输入最高价格"
          value={maxPrice}
          onChange={(e) => setMaxPrice(e.target.value)}
        />
      </div>

      {/* 商品列表展示 */}
      <div className="products-grid">
        {filteredProducts.map(product => (
          <div key={product._id} className="product-card">
            <h4>{product.name}</h4>
            <p className="price">${product.price.toFixed(2)}</p>
            {/* 其他商品信息 */}
          </div>
        ))}
      </div>
    </div>
  );
}

export default ProductPriceFilter;

场景2:数据量较大(上千条)—— 请求后端接口筛选

这种情况必须让MongoDB来做筛选,前端只需要把价格参数传给后端,拿到过滤后的结果再展示。修改前端的请求逻辑就行:

// 替换之前的useEffect,改成请求后端筛选接口
useEffect(() => {
  const fetchFilteredProducts = async () => {
    try {
      // 构建查询参数
      const params = new URLSearchParams();
      if (minPrice) params.append('minPrice', minPrice);
      if (maxPrice) params.append('maxPrice', maxPrice);

      const res = await fetch(`/api/products?${params.toString()}`);
      const data = await res.json();
      setFilteredProducts(data);
    } catch (err) {
      console.error('筛选商品失败:', err);
    }
  };

  // 避免用户快速输入时频繁请求,加个防抖延迟
  const timer = setTimeout(() => {
    fetchFilteredProducts();
  }, 300);

  return () => clearTimeout(timer);
}, [minPrice, maxPrice]);
后端Node.js/Express + MongoDB实现部分

接下来要在后端写一个支持价格范围筛选的接口,利用MongoDB的查询操作符$gte(大于等于)和$lte(小于等于):

1. 商品模型(models/Product.js)

确保你的商品模型里有price字段:

const mongoose = require('mongoose');

const productSchema = new mongoose.Schema({
  name: { type: String, required: true },
  price: { type: Number, required: true },
  // 其他字段比如description、category等...
});

module.exports = mongoose.model('Product', productSchema);

2. 商品路由(routes/products.js)

编写处理筛选请求的GET接口:

const express = require('express');
const router = express.Router();
const Product = require('../models/Product');

// 获取筛选后的商品列表
router.get('/', async (req, res) => {
  try {
    const { minPrice, maxPrice } = req.query;
    const query = {};

    // 构建价格筛选条件
    if (minPrice) {
      query.price = { ...query.price, $gte: parseFloat(minPrice) };
    }
    if (maxPrice) {
      query.price = { ...query.price, $lte: parseFloat(maxPrice) };
    }

    // 查询数据库
    const products = await Product.find(query);
    res.json(products);
  } catch (err) {
    res.status(500).json({ message: '服务器错误', error: err.message });
  }
});

module.exports = router;
一些实用提示
  • 别忘了给价格输入框加类型校验,比如限制只能输入数字,避免非数字值导致的错误;
  • 如果需要更友好的交互,可以加“重置筛选”按钮,清空minPrice和maxPrice状态;
  • 数据量大的话,还可以给MongoDB的price字段加索引,提升查询速度:在模型里给price字段加index: true;
  • 前端可以加个加载状态,在请求后端时显示加载动画,提升用户体验。

内容的提问来源于stack exchange,提问作者Azizul Tareq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 18:52:42