import React, { useState, useCallback, useEffect } from 'react'; import { View, Text, Image, ScrollView } from '@tarojs/components'; import Taro, { usePullDownRefresh, useReachBottom } from '@tarojs/taro'; import { useThrottledDidShow } from '@/hooks/useThrottledDidShow'; import { listArticles, listCategories, Article, ArticleCategory } from '../../services/article'; import EmptyState from '../../components/EmptyState'; import Loading from '../../components/Loading'; import { useElderClass } from '../../hooks/useElderClass'; import './index.scss'; export default function ArticleList() { const modeClass = useElderClass(); const [articles, setArticles] = useState([]); const [page, setPage] = useState(1); const [total, setTotal] = useState(0); const [loading, setLoading] = useState(false); const [categories, setCategories] = useState([]); const [activeCategory, setActiveCategory] = useState(null); const fetchCategories = useCallback(async () => { try { const data = await listCategories(); setCategories(data || []); } catch { setCategories([]); } }, []); const fetchData = useCallback(async (p: number, append = false, categoryId?: string | null) => { setLoading(true); try { const cid = categoryId !== undefined ? categoryId : activeCategory; const res = await listArticles({ page: p, category_id: cid || undefined, }); const list = res.data || []; setArticles(append ? (prev) => [...prev, ...list] : list); setTotal(res.total); setPage(p); } catch { Taro.showToast({ title: '加载失败', icon: 'none' }); } finally { setLoading(false); } }, [activeCategory]); useEffect(() => { fetchCategories(); }, [fetchCategories]); useThrottledDidShow(() => { fetchData(1, false, null); }, 10000); usePullDownRefresh(() => { fetchData(1, false, null).finally(() => { Taro.stopPullDownRefresh(); }); }); useReachBottom(() => { if (!loading && articles.length < total) { fetchData(page + 1, true); } }); const handleCategoryChange = (categoryId: string | null) => { setActiveCategory(categoryId); fetchData(1, false, categoryId); }; const goToDetail = (id: string) => { Taro.navigateTo({ url: `/pages/article/detail/index?id=${id}` }); }; return ( {/* 分类筛选 */} {categories.length > 0 && ( handleCategoryChange(null)} > 全部 {categories.map((cat) => ( handleCategoryChange(cat.id)} > {cat.name} ))} )} {articles.map((a) => ( goToDetail(a.id)} > {a.title} {a.summary && ( {a.summary} )} {(a.category_name || a.category) && ( {a.category_name || a.category} )} {a.published_at && ( {a.published_at.slice(0, 10)} )} {a.cover_image && ( )} ))} {articles.length === 0 && !loading && ( )} {loading && ( )} ); }