React组件分页API数据页面内容不更新问题求助
问题:React分页数据累加后页面无法逐页刷新
我正在使用一个返回结果包含下一页游标参数的API,尝试将所有分页响应数据存入变量并渲染,且希望每次获取API响应后刷新页面内容。但目前仅前两页内容会更新,经排查API返回的各页数据均正常,data变量也已正确累加所有页数据。请求解决页面内容无法随每次API响应刷新的问题。
相关代码
export default function testComponent() { let data let page = 0 let next = null const [content, setContent] = useState(null); useEffect(() => { const fetchContent = async () => { try { while(page < 5) { const result = await getPage(next); next = result.pagination.cursor await result.data.map((item) => { data.push(item) }) page++; setContent(data); } } catch (error) { console.error('Error:', error); } }; console.log("useEffect trigger") fetchContent(); }, []); if (content === null) { return ( <ImageBackground source={require('../../Components/Images/bg.png')} style={styles.backgroundImage} imageStyle={{ opacity: 0.2}}> <View> <ActivityIndicator color='#FFF'/> </View> </ImageBackground> ); } return( <ImageBackground source={require('../../Components/Images/bg.png')} style={styles.backgroundImage} imageStyle={{ opacity: 0.2}}> <View> <ScrollView> {data.map(item => { return <PageItem item={item} key={item.id}/> })} </ScrollView> </View> </ImageBackground> ) }
问题分析与修复方案
核心问题点
- 普通变量无法触发重渲染:
data、page、next是普通变量,组件每次渲染都会重置这些值,且修改它们不会触发React的重渲染机制。 - 状态更新引用未变化:
setContent(data)每次传递的都是同一个数组引用,React会判定状态未发生改变,因此不会触发页面刷新。 - 渲染依赖错误变量:页面渲染时用的是普通变量
data而非状态content,即便状态更新也无法同步到视图。 - 冗余的await调用:
map不是异步函数,await result.data.map(...)完全没必要。
修复后的代码
import { useState, useEffect, useRef } from 'react'; export default function testComponent() { const [content, setContent] = useState([]); const pageRef = useRef(0); const nextRef = useRef(null); useEffect(() => { const fetchContent = async () => { try { let isMounted = true; while (pageRef.current < 5 && isMounted) { const result = await getPage(nextRef.current); nextRef.current = result.pagination.cursor; // 创建新数组更新状态,确保引用变化触发重渲染 setContent(prev => [...prev, ...result.data]); pageRef.current++; } return () => { isMounted = false; }; } catch (error) { console.error('Error:', error); } }; fetchContent(); }, []); if (content.length === 0) { return ( <ImageBackground source={require('../../Components/Images/bg.png')} style={styles.backgroundImage} imageStyle={{ opacity: 0.2}}> <View> <ActivityIndicator color='#FFF'/> </View> </ImageBackground> ); } return( <ImageBackground source={require('../../Components/Images/bg.png')} style={styles.backgroundImage} imageStyle={{ opacity: 0.2}}> <View> <ScrollView> {content.map(item => { return <PageItem item={item} key={item.id}/> })} </ScrollView> </View> </ImageBackground> ) }
关键改动说明
- 用useState管理数据状态:将
content作为唯一的数据源,每次更新都通过setContent创建新数组([...prev, ...result.data]),确保引用变化触发重渲染。 - 用useRef跟踪分页状态:
pageRef和nextRef用来记录当前页码和下一页游标,它们的变化不会触发重渲染,适合存储不需要同步到视图的状态。 - 渲染依赖状态变量:页面渲染时遍历
content状态而非普通变量,确保视图和状态同步。 - 添加组件挂载状态判断:防止组件卸载后异步请求仍执行,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Victor Matheus
相关产品推荐
相关产品推荐

