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

点击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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 11:15:57