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

React Hooks+Redux实现子组件复选框筛选数据传值给父产品列表

实现方案(Props回调方式,无需改动Redux逻辑,适配当前场景)


第一步:修改父组件 ProductList.jsx

  1. 新增状态存储筛选后的产品列表,定义筛选回调函数传递给子组件
  2. 渲染产品时优先使用筛选后的列表,无筛选条件时默认展示全量产品
    修改后完整代码:
const ProductList = () => {
  const dispatch = useDispatch();
  // 新增状态:存储筛选后的产品列表
  const [filteredProducts, setFilteredProducts] = useState([]);
  
  const getalldatafromserver = useSelector((state)=>{
    return state.FetchALLProducts;
  })

  useEffect(() => {
    dispatch(allActions.fetchallproducts());
  }, [])

  // 新增:产品数据加载完成后默认初始化筛选列表为全量数据
  useEffect(() => {
    setFilteredProducts(getalldatafromserver.products)
  }, [getalldatafromserver.products])

  // 新增:接收子组件传递的筛选结果的回调函数
  const handleFilterChange = (filteredList) => {
    setFilteredProducts(filteredList)
  }

  return (
    <React.Fragment>
      <div className="container">
        <div className="row">
          <div className="col-md-2">
            {/* 给子组件传递回调函数 */}
            <SideNav onFilter={handleFilterChange} /> 
          </div>
          <div className="col-md-10">
            <section className="mt-3">
              <div className="container">
                <div className="row">
                  <div className="col">
                    <p className="h3 text-success">Product List</p>
                    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ex impedit, incidunt ipsum nulla sapiente sint suscipit? A animi, error et fuga ipsum minus, nam officia praesentium quisquam, recusandae soluta voluptate?</p>
                  </div>
                </div>
              </div>
            </section>
            <section>
              <div className="container">
                <div className="row">
                  {
                    filteredProducts.length > 0 &&
                    filteredProducts.map(product => {
                      return (
                        <div className="col-md-3" key={product.id}>
                          <div className="card">
                            <div className="card-header text-center bg-white">
                              <img src={product.image} alt="" width="150" height="150"/>
                            </div>
                            <div className="card-body rgba-light-green-light">
                              <ul className="list-group">
                                <li className="list-group-item">
                                  NAME : {product.name}
                                </li>
                                <li className="list-group-item">
                                  PRICE : {product.price}
                                </li>
                                <li className="list-group-item">
                                  QTY : {product.qty} Kgs
                                </li>
                              </ul>
                            </div>
                          </div>
                        </div>
                      )
                    })
                  }
                </div>
                <div className="row">
                  <div className="col">
                    {
                      filteredProducts.length === 0 &&
                      <p  className="font-weight-bold text-success text-center fw-bold">NO Records Found in Database</p>
                    }
                  </div>
                </div>
              </div>
            </section>
          </div>
        </div>
      </div>
    </React.Fragment>
  )
}

第二步:修改子组件 SideNav.jsx

  1. 接收父组件传递的onFilter回调
  2. 修正筛选逻辑:每次复选框变化(包括全选)时,先获取所有已勾选的产品名称,再筛选出匹配的全部产品,调用回调传递给父组件
    修改后完整代码:
const SideNav = ({onFilter}) => {
  //Get data from Store
  const getDataFromStore = useSelector((state)=>{
    return state.FetchALLProducts;
  })
  const [sidebar, setsidebar] = useState(false);
  const [checkBoxes, setcheckBoxes] = useState([
    {name:"Orange",isChecked:false},
    {name:"Carrot",isChecked:false},
    {name:"Apple",isChecked:false},
    {name:"Potato",isChecked:false},
    {name:"Avacados",isChecked:false}
  ])

  const showSidebar =() =>{
    setsidebar(true);
  }

  // 新增:通用筛选方法,复选框变化/全选时都调用
  const filterProducts = (checkboxList) => {
    const allProducts = [...getDataFromStore.products];
    // 获取所有已勾选的产品名称
    const checkedNames = checkboxList.filter(item => item.isChecked).map(item => item.name);
    let filteredList = allProducts;
    // 有勾选条件时筛选,无勾选时返回全量
    if(checkedNames.length > 0){
      filteredList = allProducts.filter(product => checkedNames.includes(product.name))
    }
    // 调用父组件回调传递筛选结果
    onFilter(filteredList)
  }

  const handleCheckChnage =(e) =>{
    const allcheckboxes = [...checkBoxes];
    allcheckboxes.forEach((cbox)=>{
      if(cbox.name === e.target.value){
        cbox.isChecked = !cbox.isChecked
      }
    })
    setcheckBoxes(allcheckboxes);
    // 调用筛选方法
    filterProducts(allcheckboxes)
  }

  const selectAll =(e) =>{
    const newcheckboxes = [...checkBoxes];
    newcheckboxes.forEach((allbox)=>{
      allbox.isChecked = e.target.checked;
    })
    setcheckBoxes(newcheckboxes);
    // 调用筛选方法
    filterProducts(newcheckboxes)
  }

  return (
    <React.Fragment>
      <i className="fas fa-align-justify yes" onClick={showSidebar} ></i>
      {
        sidebar &&
        <div className="form-group mt-3">
          <label className="mb-2 fw-bold">Choose Health</label> <br/>
          <input className="form-check-input" type="checkbox" name="all" onChange={(e)=>{selectAll(e)}} />
          <span style={{marginLeft:'5px',fontWeight:"bold"}}>All Skils</span>
          {
            checkBoxes.map((cb)=>
              <div className="form-check" key={cb.name}>
                <label className="form-check-label" >{cb.name}</label>
                <input className="form-check-input" type="checkbox" name="checking" value={cb.name} checked={cb.isChecked} onChange={(e)=>{handleCheckChnage(e)}} />
              </div>
            ) 
          }
        </div>
      }
    </React.Fragment>
  )
}

export default SideNav;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 13:48:01