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

React收藏功能仅保留最新值,如何获取所有已点击收藏的商品

问题原因

你当前的收藏状态favProduct定义在每个独立的Fav组件内部,每个商品对应的Fav组件的状态都是互相隔离的,无法汇总所有收藏的商品,你看到的打印结果始终是当前点击的Fav组件自己的收藏列表,自然只会保留最新点击的商品。

解决思路

把收藏列表的状态提升到公共父组件HomeScreen中维护,再将更新收藏的方法透传给所有Fav组件,实现全局收藏数据的统一管理。

修改后的代码

1. 修改HomeScreen组件

import React , { useState, useEffect } from 'react'
import { Row , Col } from 'react-bootstrap'
import Product from '../components/Product'
import axios from 'axios'

const HomeScreen = () =>{
    const [products , setProducts]  = useState([])
    // 新增全局收藏列表状态
    const [favProducts, setFavProducts] = useState([])

    // 新增切换收藏的公共方法
    const toggleFav = (product) => {
        setFavProducts(prev => {
            // 已收藏则移除,未收藏则添加,避免重复
            const isExist = prev.find(item => item._id === product._id)
            if (isExist) {
                return prev.filter(item => item._id !== product._id)
            } else {
                return [...prev, product]
            }
        })
    }

    useEffect(()=>{
        let componentMounted = true
        const fetchProducts = async () =>{
            const {data} = await axios.get('http://172.30.246.130:5000/api/products')
            if( componentMounted){
                setProducts(data)
            }
        }
        fetchProducts()
        return () =>{
            componentMounted = false
        }
    },[])
    // 这里可以打印全局的所有收藏商品
    console.log('所有收藏商品:', favProducts)
    return(
        <>
        <h2 className='my-3'>Latest Products</h2>
        <Row>
            {
                products.map((product)=>(
                    <Col key={product._id} sm={12} md={6} lg={4} xl={3}>
                        <!-- 把toggleFav方法和全局收藏列表传给Product组件 -->
                        <Product 
                            product={product} 
                            rating = {product.rating} 
                            reviews={product.numReviews}
                            toggleFav={toggleFav}
                            favProducts={favProducts}
                        />
                    </Col>
                ))
            }
        </Row>
        </>
    )
}
export default HomeScreen

2. 修改Product组件(需要新增透传参数给Fav)

在你现有的Product组件中,找到引用Fav的位置,新增传参:

// 假设你的Product组件接收了toggleFav和favProducts参数
<Fav 
    product={product} 
    toggleFav={toggleFav} 
    isFav={favProducts.some(item => item._id === product._id)}
/>

3. 修改Fav组件

import React from 'react'

// 接收父组件传的参数,不需要自己维护收藏列表和选中状态
const Fav = ({product, toggleFav, isFav}) => {
    const handleClick = () => {
        toggleFav(product)
    }
    return (
        <>
        <span onClick={handleClick}>
            <i className={isFav ? "fas fa-heart" : "far fa-heart"}></i>
        </span>
        </>
    )
}
export default Fav

额外优化

这个方案同时解决了两个原有逻辑问题:

  • 避免同一个商品被重复添加到收藏列表
  • 爱心选中状态和全局收藏数据完全同步,不会出现状态不一致的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 21:36:03