expo-popcore-app/hooks/use-template-favorite.examp...

4.4 KiB
Raw Blame History

useTemplateFavorite Hook 使用示例

基本用法

import { useTemplateFavorite } from '@/hooks'

function MyComponent() {
  const templateId = 'template-123'

  const {
    favorited,      // 当前收藏状态
    loading,        // 加载状态
    error,          // 错误信息
    favorite,       // 收藏方法
    unfavorite,     // 取消收藏方法
    checkFavorited, // 检查收藏状态方法
  } = useTemplateFavorite(templateId)

  // 收藏模板
  const handleFavorite = async () => {
    const { data, error } = await favorite()
    if (error) {
      console.error('收藏失败', error)
    } else {
      console.log('收藏成功')
    }
  }

  // 取消收藏
  const handleUnfavorite = async () => {
    const { data, error } = await unfavorite()
    if (error) {
      console.error('取消收藏失败', error)
    } else {
      console.log('取消收藏成功')
    }
  }

  // 检查收藏状态
  const handleCheck = async () => {
    const { data, error } = await checkFavorited()
    if (error) {
      console.error('检查失败', error)
    } else {
      console.log('收藏状态:', data?.favorited)
    }
  }

  return (
    <View>
      <Text>收藏状态: {favorited ? '已收藏' : '未收藏'}</Text>
      {loading && <Text>加载中...</Text>}
      {error && <Text>错误: {error.message}</Text>}

      <Button onPress={handleFavorite} disabled={loading}>
        收藏
      </Button>
      <Button onPress={handleUnfavorite} disabled={loading}>
        取消收藏
      </Button>
      <Button onPress={handleCheck} disabled={loading}>
        检查状态
      </Button>
    </View>
  )
}

带初始状态的用法

function MyComponent({ templateId, initialFavorited }: Props) {
  const { favorited, favorite, unfavorite, loading } =
    useTemplateFavorite(templateId, initialFavorited)

  return (
    <TouchableOpacity onPress={favorited ? unfavorite : favorite}>
      <Icon name={favorited ? 'heart' : 'heart-o'} />
      {loading && <ActivityIndicator />}
    </TouchableOpacity>
  )
}

检查收藏状态(组件加载时)

function TemplateCard({ template }: { template: Template }) {
  const { favorited, loading, checkFavorited } =
    useTemplateFavorite(template.id)

  useEffect(() => {
    // 组件加载时检查收藏状态
    checkFavorited()
  }, [])

  return (
    <View>
      <Text>{template.title}</Text>
      <Text>
        {loading
          ? '检查中...'
          : favorited
            ? '已收藏'
            : '未收藏'}
      </Text>
    </View>
  )
}

空值处理

function MyComponent() {
  // 不传 templateId所有方法都不会调用 API
  const { favorite, unfavorite, checkFavorited } = useTemplateFavorite()

  // 这些调用都会安全地返回 { data: null, error: null }
  await favorite()
  await unfavorite()
  await checkFavorited()
}

API 接口

参数

useTemplateFavorite(templateId?: string, initialFavorited?: boolean)
  • templateId: 模板 ID可选
  • initialFavorited: 初始收藏状态(默认 false

返回值

{
  favorited: boolean          // 当前收藏状态
  loading: boolean            // 加载状态
  error: ApiError | null      // 错误信息
  favorite: () => Promise<{   // 收藏方法
    data: SuccessResponse | null
    error: ApiError | null
  }>
  unfavorite: () => Promise<{ // 取消收藏方法
    data: SuccessResponse | null
    error: ApiError | null
  }>
  checkFavorited: () => Promise<{ // 检查收藏状态方法
    data: CheckFavoritedResponse | null
    error: ApiError | null
  }>
}

类型定义

type ApiError = {
  status?: number
  statusText?: string
  message: string
}

type SuccessResponse = {
  success: boolean
}

type CheckFavoritedResponse = {
  favorited: boolean
}

注意事项

  1. templateId 为空时:所有方法都不会调用 API而是返回 { data: null, error: null }
  2. 加载状态:任一方法执行时,loading 都会设为 true
  3. 错误处理:每次调用都会更新 error 状态,成功时会清除之前的错误
  4. 状态更新
    • favorite() 成功后,favorited 设为 true
    • unfavorite() 成功后,favorited 设为 false
    • checkFavorited() 成功后,favorited 根据返回值更新
  5. 性能优化:所有方法都使用 useCallback 缓存,依赖项为 templateId