点击BtnFavs触发Favorites的useEffect刷新数据,求替代全局Context的方案
替代全局Context的简洁方案
核心需求是点击BtnFav后,让Favorites组件重新拉取最新收藏数据。除了全局Context,以下两种轻量化方案更简洁:
方案一:回调函数传递更新通知
通过组件props传递回调,让BtnFav触发父组件的刷新逻辑,无需全局状态:
修改后代码示例
Favorites组件
const fetchWines = async () => { try { const vinos = await axios.get(`/api/favoritos/${id}`); const arrVinos = vinos.data.map((vino) => vino.product); setVinosFavs(arrVinos); } catch (err) { console.error(err); } }; useEffect(() => { fetchWines(); }, []); // 定义刷新回调,传给子组件 const refreshFavorites = () => { fetchWines(); }; return ( <div> <h1>我的收藏</h1> {/* 把回调传给Card组件 */} <Card listWines={vinosFavs} onFavChange={refreshFavorites} /> </div> );
Card组件(中间层)
需将回调继续传递给BtnFav:
const Card = ({ listWines, onFavChange }) => { return ( <div className="card-container"> {listWines.map(wine => ( <BtnFav key={wine.id} product={wine} onFavChange={onFavChange} boton={/* 根据是否收藏设置初始值 */} /> ))} </div> ); };
BtnFavs组件
点击操作完成后触发回调,通知父组件刷新:
const handleClickFav = (e) => { if (!boton) { axios.post("/api/favoritos/add", { userId, productId }).then(() => { setBoton(true); onFavChange(); }); } else { axios.put("/api/favoritos/delete ", { userId, productId }).then(() => { setBoton(false); onFavChange(); }); } };
方案二:状态提升(集中逻辑到父组件)
把收藏操作和刷新逻辑都放在Favorites组件,子组件仅负责渲染和触发事件:
修改后代码示例
Favorites组件
const fetchWines = async () => { try { const vinos = await axios.get(`/api/favoritos/${id}`); const arrVinos = vinos.data.map((vino) => vino.product); setVinosFavs(arrVinos); } catch (err) { console.error(err); } }; useEffect(() => { fetchWines(); }, []); // 收藏切换逻辑放在父组件 const toggleFavorite = async (productId) => { try { const isFavorited = vinosFavs.some(wine => wine.id === productId); if (isFavorited) { await axios.put("/api/favoritos/delete ", { userId, productId }); } else { await axios.post("/api/favoritos/add", { userId, productId }); } // 操作完成后刷新数据 fetchWines(); } catch (err) { console.error(err); } }; return ( <div> <h1>我的收藏</h1> <Card listWines={vinosFavs} toggleFavorite={toggleFavorite} /> </div> );
Card组件
const Card = ({ listWines, toggleFavorite }) => { return ( <div className="card-container"> {listWines.map(wine => { const isFavorited = true; // 根据实际收藏状态赋值 return ( <BtnFav key={wine.id} boton={isFavorited} onClick={() => toggleFavorite(wine.id)} /> ); })} </div> ); };
BtnFavs组件
仅负责渲染图标和触发点击:
const BtnFavs = ({ boton, onClick }) => { return ( <button onClick={onClick}> {boton ? '❤️' : '🤍'} </button> ); };
方案对比
- 回调函数方案:适合子组件需要保留部分操作逻辑的场景,代码侵入性低,无需全局状态。
- 状态提升方案:核心逻辑集中在父组件,子组件更轻量化,维护成本更低,适合逻辑简单的场景。
内容的提问来源于stack exchange,提问作者Gabriel
相关产品推荐
相关产品推荐

