You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中setCurrentPage无法变更currentPage状态问题求助

问题修复方案

问题根源

  1. 数据切片逻辑仅执行一次:初始请求时仅根据默认的currentPage切片数据,后续点击分页按钮更新currentPage后,currentPosts不会自动重新计算,导致页面内容无变化,看起来像是状态没更新。
  2. useEffect依赖不全:空依赖数组让组件仅在挂载时请求一次数据,后续currentPage变化无法触发数据重新处理。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 20:57:11