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

188 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# useTemplateFavorite Hook 使用示例
## 基本用法
```typescript
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>
)
}
```
## 带初始状态的用法
```typescript
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>
)
}
```
## 检查收藏状态(组件加载时)
```typescript
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>
)
}
```
## 空值处理
```typescript
function MyComponent() {
// 不传 templateId所有方法都不会调用 API
const { favorite, unfavorite, checkFavorited } = useTemplateFavorite()
// 这些调用都会安全地返回 { data: null, error: null }
await favorite()
await unfavorite()
await checkFavorited()
}
```
## API 接口
### 参数
```typescript
useTemplateFavorite(templateId?: string, initialFavorited?: boolean)
```
- `templateId`: 模板 ID可选
- `initialFavorited`: 初始收藏状态(默认 `false`
### 返回值
```typescript
{
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
}>
}
```
### 类型定义
```typescript
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`