From 7d160d55ea06c35a2980d372086d04136f8d11c7 Mon Sep 17 00:00:00 2001 From: imeepos Date: Fri, 23 Jan 2026 19:26:24 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4=E5=AF=B9=20@tanstack/?= =?UTF-8?q?react-query=20=E7=9A=84=E4=BE=9D=E8=B5=96=EF=BC=8C=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E9=A1=B9=E7=9B=AE=E7=8E=B0=E6=9C=89=20hooks=20?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 项目未安装 @tanstack/react-query,将 useWorksSearch hook 改为使用项目现有的模式: - 使用 useState 管理状态 - 使用 useCallback 封装逻辑 - 使用 useEffect 自动执行搜索 - 使用 handleError 统一错误处理 Co-Authored-By: Claude --- hooks/use-works-search.ts | 91 +++++++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 37 deletions(-) diff --git a/hooks/use-works-search.ts b/hooks/use-works-search.ts index 8e9ce28..f8edecc 100644 --- a/hooks/use-works-search.ts +++ b/hooks/use-works-search.ts @@ -2,17 +2,19 @@ * TDD Phase 2: GREEN - Minimal code to pass tests * * This Hook implements works search functionality: - * - Uses @tanstack/react-query for data fetching * - Supports keyword search * - Supports category filter * - Supports pagination * - Only executes query when keyword is provided */ -import { useQuery } from '@tanstack/react-query' import { root } from '@repo/core' import { TemplateGenerationController } from '@repo/sdk' -import { useCallback } from 'react' +import { useCallback, useEffect, useState } from 'react' + +import { type ApiError } from '@/lib/types' + +import { handleError } from './use-error' // Type definitions export interface UseWorksSearchParams { @@ -45,7 +47,7 @@ export interface WorksSearchResponse { * Hook for searching works with keyword and category filtering * * @param params - Search parameters including keyword, category, page, and limit - * @returns Query result with data, loading state, error, and refetch function + * @returns Object with data, loading state, error, and refetch function * * @example * ```tsx @@ -58,47 +60,62 @@ export interface WorksSearchResponse { * ``` */ export function useWorksSearch(params: UseWorksSearchParams) { + const [loading, setLoading] = useState(false) + const [error, setError] = useState(null) + const [data, setData] = useState(undefined) + const { keyword, category, page = 1, limit = 20 } = params - // Build query key - "全部" category should not be included - const queryKey = [ - 'worksSearch', - keyword, - category === '全部' ? undefined : category, - page, - limit, - ] as const + const execute = useCallback(async () => { + // Only execute query when keyword has content + const trimmedKeyword = keyword?.trim() || '' + if (!trimmedKeyword) { + setData(undefined) + setError(null) + return { data: undefined, error: null } + } - // Build API params - only include category if it's not "全部" - const apiParams = { - keyword, - ...(category && category !== '全部' && { category }), - page, - limit, - } + setLoading(true) + setError(null) - // Query function - const queryFn = useCallback(async (): Promise => { - const controller = root.get(TemplateGenerationController) - const result = await controller.list(apiParams) - return result as WorksSearchResponse + // Build API params - only include category if it's not "全部" + const apiParams = { + keyword: trimmedKeyword, + ...(category && category !== '全部' && { category }), + page, + limit, + } + + const templateGeneration = root.get(TemplateGenerationController) + const { data: result, error: err } = await handleError(async () => + await templateGeneration.list(apiParams) + ) + + if (err) { + setError(err) + setLoading(false) + return { data: undefined, error: err } + } + + setData(result as WorksSearchResponse) + setLoading(false) + return { data: result as WorksSearchResponse, error: null } }, [keyword, category, page, limit]) - // Execute query only when keyword has content - const trimmedKeyword = keyword?.trim() || '' - const isEnabled = !!trimmedKeyword + // Auto-execute search when params change + useEffect(() => { + execute() + }, [execute]) - const query = useQuery({ - queryKey, - queryFn, - enabled: isEnabled, - }) + const refetch = useCallback(() => { + return execute() + }, [execute]) return { - data: query.data, - works: query.data?.data || [], - isLoading: query.isLoading, - error: query.error, - refetch: query.refetch, + data, + works: data?.data || [], + isLoading: loading, + error, + refetch, } }