时里院子市集
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

7.8 KiB

🏪 useShopInfo Hook 使用指南

📋 概述

useShopInfo 是一个用于管理商店信息的React Hook,提供了商店信息的获取、缓存和管理功能。它基于getShopInfo()接口,为全站提供统一的商店信息访问方式。

特性

  • 🚀 自动缓存:30分钟本地缓存,减少网络请求
  • 🔄 智能刷新:支持强制刷新和自动过期更新
  • 📱 离线支持:网络失败时使用缓存数据
  • 🛠️ 工具方法:提供常用信息的便捷获取方法
  • 🎯 TypeScript:完整的类型支持
  • 性能优化:使用useCallback避免不必要的重渲染

🔧 基本用法

1. 导入Hook

import { useShopInfo } from '@/hooks/useShopInfo';

2. 在组件中使用

const MyComponent = () => {
  const { 
    shopInfo, 
    loading, 
    error,
    getWebsiteName,
    getWebsiteLogo 
  } = useShopInfo();

  if (loading) {
    return <div>加载中...</div>;
  }

  if (error) {
    return <div>加载失败: {error}</div>;
  }

  return (
    <div>
      <img src={getWebsiteLogo()} alt="Logo" />
      <h1>{getWebsiteName()}</h1>
    </div>
  );
};

📊 API 参考

状态属性

属性 类型 说明
shopInfo CmsWebsite | null 商店信息对象
loading boolean 是否正在加载
error string | null 错误信息

方法

方法 参数 返回值 说明
fetchShopInfo forceRefresh?: boolean Promise<CmsWebsite | null> 获取商店信息
refreshShopInfo - Promise<CmsWebsite | null> 强制刷新商店信息
clearCache - void 清除本地缓存

工具方法

方法 返回值 说明
getWebsiteName() string 获取网站名称,默认"商城"
getWebsiteLogo() string 获取网站Logo URL
getDarkLogo() string 获取深色模式Logo URL
getDomain() string 获取网站域名
getPhone() string 获取联系电话
getEmail() string 获取邮箱地址
getAddress() string 获取地址
getIcpNo() string 获取ICP备案号
getStatus() object 获取网站状态信息
getConfig() any 获取网站配置
getNavigation() object 获取导航菜单
isSearchEnabled() boolean 是否支持搜索
getVersionInfo() object 获取版本信息

🎯 使用场景

1. 页面头部组件

// src/pages/index/Header.tsx
import { useShopInfo } from '@/hooks/useShopInfo';

const Header = () => {
  const { getWebsiteName, getWebsiteLogo, loading } = useShopInfo();

  return (
    <NavBar
      left={
        <div style={{display: 'flex', alignItems: 'center'}}>
          <Avatar size="22" src={getWebsiteLogo()} />
          <span>{getWebsiteName()}</span>
        </div>
      }
    />
  );
};

2. 首页组件

// src/pages/index/index.tsx
import { useShopInfo } from '@/hooks/useShopInfo';

const Home = () => {
  const { shopInfo, loading, error } = useShopInfo();

  useEffect(() => {
    if (shopInfo) {
      // 设置页面标题
      Taro.setNavigationBarTitle({
        title: shopInfo.websiteName || '商城'
      });
    }
  }, [shopInfo]);

  // 分享配置
  useShareAppMessage(() => ({
    title: shopInfo?.websiteName || '精选商城',
    imageUrl: shopInfo?.websiteLogo
  }));

  return (
    <div>
      {/* 页面内容 */}
    </div>
  );
};

3. 商品详情页分享

// src/shop/goodsDetail/index.tsx
import { useShopInfo } from '@/hooks/useShopInfo';

const GoodsDetail = () => {
  const { getWebsiteName, getWebsiteLogo } = useShopInfo();

  useShareAppMessage(() => ({
    title: `${goods?.name} - ${getWebsiteName()}`,
    path: `/shop/goodsDetail/index?id=${goodsId}`,
    imageUrl: goods?.image || getWebsiteLogo()
  }));

  return (
    <div>
      {/* 商品详情 */}
    </div>
  );
};

4. 联系我们页面

const ContactPage = () => {
  const { 
    getPhone, 
    getEmail, 
    getAddress, 
    getIcpNo 
  } = useShopInfo();

  return (
    <div>
      <div>电话: {getPhone()}</div>
      <div>邮箱: {getEmail()}</div>
      <div>地址: {getAddress()}</div>
      <div>备案号: {getIcpNo()}</div>
    </div>
  );
};

5. 网站状态检查

const StatusChecker = () => {
  const { getStatus, getVersionInfo } = useShopInfo();
  
  const status = getStatus();
  const version = getVersionInfo();

  return (
    <div>
      <div>运行状态: {status.running ? '正常' : '维护中'}</div>
      <div>版本: {version.version === 10 ? '免费版' : version.version === 20 ? '专业版' : '永久授权'}</div>
      {version.expirationTime && (
        <div>到期时间: {version.expirationTime}</div>
      )}
    </div>
  );
};

🔄 缓存机制

缓存策略

  • 缓存时间:30分钟
  • 存储位置:微信小程序本地存储
  • 缓存键名shop_infoshop_info_cache_time

缓存行为

  1. 首次加载:从服务器获取数据并缓存
  2. 后续加载:优先使用缓存,缓存过期时自动刷新
  3. 网络失败:使用缓存数据(即使过期)
  4. 强制刷新:忽略缓存,直接从服务器获取

手动管理缓存

const { refreshShopInfo, clearCache } = useShopInfo();

// 强制刷新
const handleRefresh = async () => {
  await refreshShopInfo();
};

// 清除缓存
const handleClearCache = () => {
  clearCache();
};

🚀 性能优化

1. 避免重复请求

// ✅ 推荐:多个组件使用同一个Hook实例
const App = () => {
  const shopInfo = useShopInfo();
  
  return (
    <ShopInfoProvider value={shopInfo}>
      <Header />
      <Content />
      <Footer />
    </ShopInfoProvider>
  );
};

2. 条件渲染优化

const Component = () => {
  const { shopInfo, loading } = useShopInfo();

  // ✅ 使用loading状态避免闪烁
  if (loading) {
    return <Skeleton />;
  }

  return (
    <div>
      {shopInfo && (
        <img src={shopInfo.websiteLogo} alt="Logo" />
      )}
    </div>
  );
};

🛠️ 迁移指南

从直接调用API迁移

迁移前

// 旧代码
const [config, setConfig] = useState<CmsWebsite>();

useEffect(() => {
  getShopInfo().then((data) => {
    setConfig(data);
  });
}, []);

迁移后

// 新代码
const { shopInfo: config, loading } = useShopInfo();

批量替换步骤

  1. 替换导入
// 删除
import { getShopInfo } from '@/api/layout';

// 添加
import { useShopInfo } from '@/hooks/useShopInfo';
  1. 替换状态管理
// 删除
const [config, setConfig] = useState<CmsWebsite>();

// 替换为
const { shopInfo: config, loading, error } = useShopInfo();
  1. 删除useEffect
// 删除这些代码
useEffect(() => {
  getShopInfo().then((data) => {
    setConfig(data);
  });
}, []);

🧪 测试示例

// 测试组件
const TestComponent = () => {
  const { 
    shopInfo, 
    loading, 
    error,
    refreshShopInfo,
    getWebsiteName 
  } = useShopInfo();

  return (
    <div>
      <div>状态: {loading ? '加载中' : '已加载'}</div>
      <div>错误: {error || '无'}</div>
      <div>网站名: {getWebsiteName()}</div>
      <button onClick={refreshShopInfo}>刷新</button>
      <pre>{JSON.stringify(shopInfo, null, 2)}</pre>
    </div>
  );
};

🎉 总结

useShopInfo Hook 提供了:

  • 统一的商店信息管理
  • 智能缓存机制
  • 丰富的工具方法
  • 完整的TypeScript支持
  • 简单的迁移路径

通过使用这个Hook,你可以在整个应用中轻松访问和管理商店信息,提高代码的可维护性和用户体验。