如何将react-infinite-scroll-component类组件转换为函数组件
问题修正说明
你写的转换代码存在以下几个典型错误,逐一修正即可正常运行:
- 导入错误:
React是默认导出,不需要放在花括号里,正确导入写法是import React, { useState } from "react" useState用法完全错误:useState返回的是**[状态值, 更新函数]**的数组,不是对象,不能用对象解构- 类组件里两个独立状态
items和hasMore,要么拆成两个独立的useState,要么合并成一个状态对象,你之前把初始值和第二个参数传错了
- 未定义更新函数:函数组件没有类组件的
this.setState全局方法,每个状态对应的更新函数是useState返回的第二个值,你直接写setState会报未定义错误 - 错误引用状态:函数组件里不存在
state.xxx的访问方式,直接用声明的状态变量即可 - 函数声明不规范:组件内部的
fetchMoreData没有加const声明,严格模式下会报错 - 闭包陷阱:setTimeout回调里直接拿
items可能拿到旧的闭包值,更新列表时推荐用函数式更新,保证拿到最新状态 - 冗余语法错误:你原始代码里
InfiniteScroll标签下多打了一个多余的>,会导致渲染异常
修正后可直接运行的代码
import React, { useState } from "react"; import { render } from "react-dom"; import InfiniteScroll from "react-infinite-scroll-component"; const style = { height: 30, border: "1px solid green", margin: 6, padding: 8 }; function App() { // 拆分两个独立状态,对应类组件里的state字段 const [items, setItems] = useState(Array.from({ length: 20 })); const [hasMore, setHasMore] = useState(true); const fetchMoreData = () => { if (items.length >= 500) { setHasMore(false); return; } // 模拟异步请求 setTimeout(() => { // 用函数式更新避免闭包拿到旧的items值 setItems(prevItems => prevItems.concat(Array.from({ length: 20 }))); }, 500); }; return ( <div> <h1>demo: react-infinite-scroll-component</h1> <hr /> <InfiniteScroll dataLength={items.length} next={fetchMoreData} hasMore={hasMore} loader={<h4>Loading...</h4>} endMessage={ <p style={{ textAlign: "center" }}> <b>Yay! You have seen it all</b> </p> } > {items.map((i, index) => ( <div style={style} key={index}> div - #{index} </div> ))} </InfiniteScroll> </div> ); } render(<App />, document.getElementById("root"));
补充说明
如果习惯类组件的对象式状态写法,也可以把两个状态合并成一个useState管理,更新的时候注意合并字段即可,不过React官方更推荐把独立变化的状态拆成多个useState,逻辑更清晰。
内容的提问来源于stack exchange,提问作者user19510473
相关产品推荐
相关产品推荐

