Next.js中setCurrentPage无法变更currentPage状态问题求助
问题修复方案
问题根源
- 数据切片逻辑仅执行一次:初始请求时仅根据默认的
currentPage切片数据,后续点击分页按钮更新currentPage后,currentPosts不会自动重新计算,导致页面内容无变化,看起来像是状态没更新。 - useEffect依赖不全:空依赖数组让组件仅在挂载时请求一次数据,后续
currentPage变化无法触发数据重新处理。 - sermon初始状态错误:初始设为
{}对象,会导致页面加载初期pages数组生成异常(sermon.length为undefined)。
修复步骤
1. 修正sermon初始状态
把sermon的初始值从对象改为空数组,确保数组相关操作(如length)正常执行:
const [sermon, setSermon] = useState([]);
2. 分离数据请求与切片逻辑
不再在请求时处理切片,而是直接基于当前currentPage和完整数据实时计算currentPosts,这样currentPage变化时会自动更新内容:
// 移除useEffect里的setCurrentPosts,改为直接计算 const currentPosts = sermon.slice(firstPostIndex, lastPostIndex); useEffect(() => { axios.get(`${process.env.NEXT_PUBLIC_SERVER_URL}/sermons`) .then((response) => { setSermon(response.data.sermons.toReversed()); setIsLoading(false); }) .catch((err) => { console.log(err); }); }, []);
3. 优化分页按钮渲染
去掉不必要的Fragment包裹,直接渲染按钮,避免潜在的key值警告:
{pages.map((page, index) => ( <button key={index} onClick={() => setCurrentPage(page)}> {page} </button> ))}
完整修复代码
import axios from "axios"; import { useEffect, useState } from "react"; import '../css/page.css'; import '../css/sermons.css'; import SermonModal from "./SermonModal"; import Pagination from '@mui/material/Pagination'; import Stack from "@mui/material/Stack"; import Pagenation from "./Pagenation"; export default function GetAllSermon() { const [sermon, setSermon] = useState([]); const [isLoading, setIsLoading] = useState(true); const [currentPage, setCurrentPage] = useState(1); const [postsPerPage, setPostsPerPage] = useState(3); const lastPostIndex = currentPage * postsPerPage; const firstPostIndex = lastPostIndex - postsPerPage; const currentPosts = sermon.slice(firstPostIndex, lastPostIndex); useEffect(() => { axios.get(`${process.env.NEXT_PUBLIC_SERVER_URL}/sermons`) .then((response) => { setSermon(response.data.sermons.toReversed()); setIsLoading(false); }) .catch((err) => { console.log(err); }); }, []); const pageCount = Math.ceil(sermon.length / postsPerPage); const pages = Array.from({length: pageCount}, (_, i) => i + 1); if (isLoading) return <div>Loading...</div>; return ( <> {currentPosts.map((sermonItem) => ( <div className="component_sermon_section" key={sermonItem._id}> <div className="sermon_snap"> <a href='#'><img src={sermonItem.snap} className='sermon_snap' /></a> </div> <div className="sermon_info" > <h3> <SermonModal sermon={sermonItem} /> </h3> <p className='date_time'> {sermonItem.date.split('T')[0]} @ {sermonItem.session === 'First' ? '8:00 AM 1부' : sermonItem.session === 'Second' ? '09:30 AM 2부' : sermonItem.session === 'Third' ? '11:00 AM 3부' : ''} - {sermonItem.preacher} 목사 </p> </div> </div> ))} {pages.map((page, index) => ( <button key={index} onClick={() => setCurrentPage(page)}> {page} </button> ))} </> ); }
额外优化
- 把
map循环里的变量名从sermon改为sermonItem,避免和外层状态变量冲突,提升代码可读性。 - 简化了日期显示的三元表达式,去掉冗余的
null判断,逻辑更清晰。
内容的提问来源于stack exchange,提问作者Jay Lee
相关产品推荐
相关产品推荐

