React组件持续触发重渲染,分页相关代码bug如何解决?
核心问题原因&解决方案
1. 分页点击事件写法错误导致死循环(最主要原因)
你的分页点击事件代码写为:
<li key={num} className="page_num" onClick={changePage(num)}> {num} </li>
这种写法会在组件每次渲染时直接执行changePage(num),而不是点击时才触发。执行后会修改page状态,触发组件重新渲染,渲染时又再次执行changePage(num),形成无限重渲染的死循环。
解决方法:用箭头函数包裹逻辑,仅点击时才执行状态更新
<li key={num} className="page_num" onClick={() => changePage(num)}> {num} </li>
2. 状态初始化逻辑冗余+命名冲突
你的代码里定义了和page状态更新函数setpage(小写p)几乎重名的自定义函数setPage(大写P),很容易引发逻辑混淆。同时初始化page的逻辑放在useEffect里执行,会在组件第一次渲染完成后额外修改一次page状态,触发不必要的重渲染。
解决方法:把page初始化逻辑直接放在useState的初始值计算中,删除冗余的自定义setPage函数
// 直接在useState中完成page初始化,不需要后续再修改 const [page, setpage] = useState(() => Number(sessionStorage.getItem("page")) || 1)
3. useEffect依赖缺失
当前你的useEffect依赖是空数组,只有组件第一次挂载时会执行拉取数据的逻辑,切换page、limit后不会重新拉取对应页的数据,功能不完整。
解决方法:把
dispatch、page、limit加到useEffect的依赖数组中,调整初始化顺序,删除useEffect里的setPage调用
useEffect(() => { async function fetchData() { let body = { limit: limit, page: page, } const res_count = await dispatch(boardcount()) const response = await dispatch(boardlist(body)) setposts(response.payload); let page_arr = [] for (let i = 1; i <= Math.ceil(res_count.payload / limit); i++) { page_arr.push(i) } setall_page(page_arr) } fetchData(); }, [dispatch, page, limit]) // 补全依赖
修改setall_page失败的原因
你写的setall_page((old) => [...old,page_arr])是把整个page_arr数组作为单个元素追加到旧数组末尾,最终all_page会变成二维数组(比如[1,2, [1,2,3]]),map遍历的时候拿到的元素不是数字而是数组,自然无法正常渲染。
你这个场景每次请求完是全量计算所有页码,不需要保留旧值,直接用setall_page(page_arr)就可以满足需求。如果确实需要追加页码,应该展开page_arr:
setall_page((old) => [...old, ...page_arr])
内容的提问来源于stack exchange,提问作者chanhong

