diff --git a/components/Footer.js b/components/Footer.js index 6b77779..1f3b56a 100644 --- a/components/Footer.js +++ b/components/Footer.js @@ -1,18 +1,16 @@ -import React, { useState, useEffect } from 'react'; +import React, { useEffect } from 'react'; import packageInfo from '../package.json'; import { useStats } from '../contexts/StatsContext'; import { HiOutlineCursorClick, HiOutlineTag, HiOutlineCode, HiOutlineGlobeAlt, HiOutlineClock } from 'react-icons/hi'; const Footer = () => { const { stats, updateStats } = useStats(); - const [loading, setLoading] = useState(false); useEffect(() => { // 如果已经有缓存的访问量,不再重复请求 if (stats.visitCount !== null) return; const fetchVisitCount = async () => { - setLoading(true); try { const response = await fetch('/api/visit-count'); if (!response.ok) { @@ -23,8 +21,6 @@ const Footer = () => { } catch (error) { console.error('获取访问量失败:', error); updateStats({ visitCount: 0 }); - } finally { - setLoading(false); } }; diff --git a/components/HeaderBar.js b/components/HeaderBar.js index d691426..74a7081 100644 --- a/components/HeaderBar.js +++ b/components/HeaderBar.js @@ -1,14 +1,12 @@ import React, { useEffect } from 'react'; import ThemeToggleButton from './ThemeToggleButton'; -import { useTheme } from '../contexts/ThemeContext'; import { useStats } from '../contexts/StatsContext'; -import { HiOutlineClock, HiOutlineGlobeAlt, HiOutlineInformationCircle, HiOutlineHome, HiOutlineSearch } from 'react-icons/hi'; +import { HiOutlineInformationCircle, HiOutlineHome, HiOutlineSearch } from 'react-icons/hi'; import Link from 'next/link'; import { useRouter } from 'next/router'; const HeaderBar = ({ lastFetched, count, searchQuery, setSearchQuery }) => { - const { mounted } = useTheme(); - const { stats, updateStats } = useStats(); + const { updateStats } = useStats(); const router = useRouter(); const isAboutPage = router.pathname === '/about'; @@ -19,10 +17,6 @@ const HeaderBar = ({ lastFetched, count, searchQuery, setSearchQuery }) => { } }, [count, lastFetched]); - // 优先使用全局 stats,如果没有则回退到 props - const displayCount = stats.count ?? count; - const displayTime = stats.lastFetched ?? lastFetched; - return (
diff --git a/components/MainPage.js b/components/MainPage.js index 98c89c2..77f9113 100644 --- a/components/MainPage.js +++ b/components/MainPage.js @@ -1,6 +1,5 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import HeaderBar from './HeaderBar'; -import Footer from './Footer'; import FontMenu from './FontMenu'; import Tags from './Tags'; import WebList from './WebList'; @@ -18,8 +17,6 @@ const MainPage = ({ initialPosts, initialTags, lastFetched: initialLastFetched } const [searchQuery, setSearchQuery] = useState(''); const [onList, setOnList] = useState([]); - const [filteredPosts, setFilteredPosts] = useState([]); - const [visibleTags, setVisibleTags] = useState(tags); // 初始化全局缓存 useEffect(() => { @@ -28,24 +25,21 @@ const MainPage = ({ initialPosts, initialTags, lastFetched: initialLastFetched } } }, [initialPosts]); - // 当源数据 posts, 标签过滤 onList 或 搜索内容 searchQuery 变化时更新结果 - useEffect(() => { - // 确保有数据时才进行过滤 - if (posts && posts.length > 0) { - const results = updateResults(posts, onList); - const finalResults = filterPostsBySearch(results, searchQuery); - const availableTags = extractTags(finalResults); - setFilteredPosts(finalResults); - setVisibleTags( - searchQuery.trim() - ? tags.filter(tag => onList.includes(tag) || availableTags.includes(tag)) - : tags - ); - } else { - setFilteredPosts([]); - setVisibleTags(searchQuery.trim() ? onList : tags); + const filteredPosts = useMemo(() => { + if (!posts || posts.length === 0) { + return []; + } + const results = updateResults(posts, onList); + return filterPostsBySearch(results, searchQuery); + }, [posts, onList, searchQuery]); + + const visibleTags = useMemo(() => { + if (!searchQuery.trim()) { + return tags; } - }, [posts, onList, searchQuery, tags]); + const availableTags = extractTags(filteredPosts); + return tags.filter(tag => onList.includes(tag) || availableTags.includes(tag)); + }, [tags, onList, searchQuery, filteredPosts]); const handleToggleTagButton = tag => { const newOnList = _.xor(onList, [tag]); diff --git a/contexts/ThemeContext.js b/contexts/ThemeContext.js index cfd9224..494b0c3 100644 --- a/contexts/ThemeContext.js +++ b/contexts/ThemeContext.js @@ -40,7 +40,7 @@ export const ThemeProvider = ({ children }) => { return () => mediaQuery.removeEventListener('change', handleChange); }, []); - const toggleTheme = (event) => { + const toggleTheme = () => { const toggle = (newTheme) => { document.documentElement.classList.toggle('dark', newTheme); diff --git a/pages/about.js b/pages/about.js index cb14dd6..0dd65ea 100644 --- a/pages/about.js +++ b/pages/about.js @@ -5,7 +5,6 @@ import FontMenu from '../components/FontMenu'; import { HiOutlineSparkles, HiOutlineCollection, HiOutlineHeart } from 'react-icons/hi'; import Head from 'next/head'; import { getDatabase } from '../lib/notion'; -import { unique } from '../lib/dataLoader'; import Link from 'next/link'; import { useStats } from '../contexts/StatsContext';