React+MUI+TS分页报错:Cannot read properties of undefined (reading 'length')
分页功能报错排查与修复
问题场景
开发基于JSON数据的分页卡片功能,期望点击「>」「<」切换页面并更新卡片内容,但遇到以下问题:
usePagination.tsx报错:Cannot read properties of undefined (reading 'length')- 分页切换卡片的预期效果未实现
现有代码
App.tsx
import { useState } from "react"; import { default as data } from "./DATA.json"; // 包含JSON对象数组 import { usePagination } from "./Pagination"; const PER_PAGE = 8; // 每页展示的卡片数量 // 错误的调用方式 const _DATA = usePagination(data, PER_PAGE); // 原代码中冗余的状态与计算(可替换为usePagination返回的值) let [page, setPage] = useState(1); const totalPages= Math.ceil(data.length / PER_PAGE);
usePagination.tsx
import { useState } from "react"; import Books from "./interfaces"; interface DataBooks { data: Books[]; itemsPerPage: number; } export const usePagination = ({ data, itemsPerPage }: DataBooks) => { const [currentPage, setCurrentPage] = useState(1); const maxPage = Math.ceil(data.length / itemsPerPage); // 此处因data未正确传入报错 function currentData() { const begin = (currentPage - 1) * itemsPerPage; const end = begin + itemsPerPage; return data.slice(begin, end); } function next() { setCurrentPage((currentPage) => Math.min(currentPage + 1, maxPage)); } function prev() { setCurrentPage((currentPage) => Math.max(currentPage - 1, 1)); } function jump(page: number) { const pageNumber = Math.max(1, page); setCurrentPage((currentPage) => Math.min(pageNumber, maxPage)); } return { next, prev, jump, currentData, currentPage, maxPage }; };
错误原因
usePagination 组件定义的参数是符合DataBooks接口的对象,但在App.tsx中调用时直接传入了两个独立参数(data和PER_PAGE),导致组件内部的data和itemsPerPage均为undefined,进而触发data.length读取错误。
修复方案
1. 修正usePagination调用方式
将App.tsx中的调用改为传入对象参数:
// 替换原错误调用 const _DATA = usePagination({ data, itemsPerPage: PER_PAGE });
2. 移除冗余状态与计算
利用usePagination返回的currentPage和maxPage替代自己维护的状态,避免冗余:
// 删除以下两行冗余代码 // let [page, setPage] = useState(1); // const totalPages= Math.ceil(data.length / PER_PAGE); // 直接解构usePagination返回的值 const { next, prev, currentData, currentPage, maxPage } = usePagination({ data, itemsPerPage: PER_PAGE });
3. 验证数据与接口匹配
确保DATA.json导出的是数组,且Books接口的结构与JSON数据的每个对象完全匹配,避免因类型不兼容导致的隐性错误。
修复后使用示例
在App.tsx中渲染卡片和分页按钮:
// 渲染当前页的卡片 currentData().forEach(item => ( <Card key={item.id}> {/* 填充卡片内容,例如{item.title}、{item.description}等 */} </Card> )); // 分页控制按钮 <button onClick={prev} disabled={currentPage === 1}> < </button> <span>第{currentPage}页 / 共{maxPage}页</span> <button onClick={next} disabled={currentPage === maxPage}> > </button>
内容的提问来源于stack exchange,提问作者Begginer
相关产品推荐
相关产品推荐

