react-infinite-scroll-component的next函数仅触发一次问题求助
React Infinite Scroll Component仅触发一次next函数问题
组件实现代码
<div id="scrollableDiv" style={{ height: 300, overflow: "auto" }}> <InfiniteScroll dataLength={texts.length} next={getText} hasMore={true} loader={<h5>Loading...</h5>} endMessage={<p style={{textAlign:'center'}}><b>Yay! You've seen it all!</b></p>} scrollableTarget="scrollableDiv" > {<Texts texts = {texts}/>} </InfiniteScroll> </div>
文本状态数组定义:
const [texts, setTexts] = useState([])
getText方法实现
const getText = async ()=>{ const res = await axios.get("http://localhost:3001/api/sth",{ params: { ids: followings.map(i => i.id), str_ids: followings.map(i => i.str_id) }, paramsSerializer: params => { return qs.stringify(params) } }); let str_ids_res = res.data.map(i => i.string_id) let texts_res = res.data.map(i => i.texts) console.log(texts_res) const filtered_res = // some processing here on texts_res /* eslint eqeqeq: 0 */ if(!arrayIsEqual(filtered_res,texts)){ console.log("Not equal") // append arrays to a array state setTexts((prevtexts) => prevtexts.concat([...filtered_res])) } }
注:接口http://localhost:3001/api/sth每次都会返回两条不同的文本,理论上setTexts每次都会被调用
Texts子组件代码
const Texts = ({texts}) =>{ return ( <> {texts.map(text =>( <div key={text.id}> <Card> <Card.Content> <Card.Description> {text.full_text} </Card.Description> </Card.Content> </Card> </div> ))} </> ); }
问题现象
尽管dataLength变量设置正确,但InfiniteScroll组件仅触发一次next函数。初始时texts为空,启动应用后仅显示'Loading....'。
解决方案
1. 排查arrayIsEqual函数逻辑
自定义的arrayIsEqual可能存在判断错误,导致新返回的数据被误判为与现有texts相等,跳过setTexts。可以临时注释掉该判断,直接执行setTexts,验证是否能触发多次加载。
2. 确认dataLength的更新
添加日志确认texts.length是否在每次setTexts后正确更新:
console.log('当前texts长度:', texts.length)
如果长度未变化,说明setTexts没有正确执行,需要检查数据处理逻辑。
3. 检查滚动容器与内容高度
如果内容总高度始终未超过滚动容器的300px,组件不会触发加载更多。可以:
- 给Card添加固定高度样式(如
style={{height: 100}}),强制内容高度超出容器 - 检查Card组件是否正确渲染,是否存在样式导致高度为0的情况
4. 调整hasMore的控制逻辑
虽然接口返回新数据,但可以用状态动态控制hasMore,避免硬编码为true:
const [hasMore, setHasMore] = useState(true); // 在getText中 const getText = async ()=>{ const res = await axios.get(...); // ...数据处理 if(filtered_res.length === 0){ setHasMore(false); } setTexts(prev => prev.concat(filtered_res)); } // 组件中 <InfiniteScroll hasMore={hasMore} // 其他属性 >
5. 验证scrollableTarget的有效性
尝试移除scrollableTarget属性,让组件监听window滚动,排查是否是滚动容器引用失败的问题。如果window滚动能触发多次加载,说明原容器的DOM引用存在问题,需要确认scrollableDiv是否正确渲染。
内容的提问来源于stack exchange,提问作者zxcisnoias
相关产品推荐
相关产品推荐

