import React, { useState, useEffect, useContext, useCallback, useRef } from 'react'; import axios from 'axios'; import Container from '@mui/material/Container'; import Grid from '@mui/material/Grid'; import Pagination from '@mui/material/Pagination'; import { Link } from 'react-router-dom'; import CircularProgress from '@mui/material/CircularProgress'; import ConfigContext from './Config'; import MovieCard from './components/MovieCard'; import CategoryNav from './components/CategoryNav'; const categories = [ { label: '15min', value: '15min' }, { label: '30min', value: '30min' }, { label: '60min', value: '60min' }, { label: '大于60min', value: '大于60min' }, ]; const LIMIT = 20; const usePersistedState = (key, defaultValue) => { const [state, setState] = useState(() => { const stored = localStorage.getItem(key); return stored ? JSON.parse(stored) : defaultValue; }); useEffect(() => { localStorage.setItem(key, JSON.stringify(state)); }, [key, state]); return [state, setState]; }; const Main = () => { const config = useContext(ConfigContext); const [loading, setLoading] = useState(false); const scrollRef = useRef(0); // 初始化状态,直接使用 categories 中的 value 值 const [params, setParams] = usePersistedState('params', { lastCategory: categories[0].value, // 直接使用 '15min' 这样的值 history: categories.reduce((acc, category) => ({ ...acc, [category.value]: { lastPage: 1, scrollPos: 0 } // 使用 category.value 作为键 }), {}) }); const [movies, setMovies] = useState([]); const [pagination, setPagination] = useState({ page: 1, total: 0, pages: 1 }); const fetchMovies = useCallback(async (category, page) => { setLoading(true); try { // 直接使用 category 值,不需要转换 const response = await axios.get( `/movie/?page=${page}&limit=${LIMIT}&category=${encodeURIComponent(category)}` ); if (response.status === 200) { const { items, total } = response.data.data; if (items.length === 0 && page > 1) { setParams(prev => ({ ...prev, history: { ...prev.history, [category]: { ...(prev.history[category] || { lastPage: 1, scrollPos: 0 }), lastPage: page - 1 } } })); return; } setMovies(items); setPagination({ page, total, pages: Math.ceil(total / LIMIT) }); requestAnimationFrame(() => { window.scrollTo(0, scrollRef.current); }); } } catch (error) { console.error('Error fetching movies:', error); } finally { setLoading(false); } }, [setParams]); const getCurrentCategoryAndPage = useCallback(() => { // 直接从 params 中获取 lastCategory,确保它是 categories 中的 value 值 const lastCategory = params.lastCategory || categories[0].value; const categoryHistory = params.history[lastCategory] || { lastPage: 1, scrollPos: 0 }; return { category: lastCategory, page: categoryHistory.lastPage }; }, [params]); useEffect(() => { const { category, page } = getCurrentCategoryAndPage(); scrollRef.current = params.history[category]?.scrollPos || 0; fetchMovies(category, page); }, [getCurrentCategoryAndPage, fetchMovies, params.history]); const handleCategoryChange = useCallback((category) => { scrollRef.current = window.scrollY; const currentCategory = params.lastCategory || categories[0].value; setParams(prev => { const newHistory = { ...prev.history, [currentCategory]: { ...(prev.history[currentCategory] || { lastPage: 1, scrollPos: 0 }), scrollPos: scrollRef.current }, [category]: { ...(prev.history[category] || { lastPage: 1, scrollPos: 0 }) } }; return { ...prev, lastCategory: category, // 直接存储传入的 category 值 history: newHistory }; }); }, [params.lastCategory, setParams]); const handlePageChange = useCallback((_, page) => { scrollRef.current = window.scrollY; const lastCategory = params.lastCategory || categories[0].value; setParams(prev => ({ ...prev, history: { ...prev.history, [lastCategory]: { ...(prev.history[lastCategory] || { lastPage: 1, scrollPos: 0 }), lastPage: page } } })); }, [params.lastCategory, setParams]); const handleMovieCardClick = useCallback(() => { scrollRef.current = window.scrollY; const lastCategory = params.lastCategory || categories[0].value; setParams(prev => ({ ...prev, history: { ...prev.history, [lastCategory]: { ...(prev.history[lastCategory] || { lastPage: 1, scrollPos: 0 }), scrollPos: scrollRef.current } } })); }, [params.lastCategory, setParams]); return ( {loading ? ( ) : ( {movies.map((item) => ( ))} )} ); }; export default Main;