List 组件通过 loading
和 hasMore
两个变量控制加载状态,当组件滚动到底部时,会触发 load
事件并将 loading
设置成 true
。此时可以发起异步操作并更新数据,数据更新完毕后,将 loading
设置成 false
即可。若数据已全部加载完毕,则直接将 hasMore
设置成 false
即可。
function BasicList() {
const [hasMore, setHasMore] = useState(true)
const [list, setList] = useState<string[]>([])
const [loading, setLoading] = useState(false)
const [scrollTop, setScrollTop] = useState(0)
usePageScroll(({ scrollTop: aScrollTop }) => setScrollTop(aScrollTop))
return (
<List
loading={loading}
hasMore={hasMore}
scrollTop={scrollTop}
onLoad={() => {
setLoading(true)
setTimeout(() => {
for (let i = 0; i < 10; i++) {
const text = list.length + 1
list.push(text < 10 ? "0" + text : String(text))
}
setList([...list])
setHasMore(list.length < 40)
setLoading(false)
}, 1000)
}}
>
{
list.map((item) => (
<Cell key={item}>{item}</Cell>
))
}
<List.Placeholder>
{loading && <Loading>加载中...</Loading>}
{!hasMore && "没有更多了"}
</List.Placeholder>
</List>
)
}
若列表数据加载失败,将 error
设置成 true
即可显示错误提示,用户点击错误提示后会重新触发 load 事件。
function ErrorList() {
const [hasMore, setHasMore] = useState(true)
const [list, setList] = useState<string[]>([])
const [loading, setLoading] = useState(false)
const [error, setError] = useState(false)
const [scrollTop, setScrollTop] = useState(0)
usePageScroll(({ scrollTop: aScrollTop }) => setScrollTop(aScrollTop))
return (
<List
loading={loading}
hasMore={hasMore}
scrollTop={scrollTop}
onLoad={() => {
setLoading(true)
setTimeout(() => {
for (let i = 0; i < 10; i++) {
const text = list.length + 1
list.push(text < 10 ? "0" + text : String(text))
}
const newList = [...list]
setHasMore(!(newList.length <= 10 || newList.length >= 40))
setError(newList.length <= 10)
setList(newList)
setLoading(false)
}, 1000)
}}
>
{
list.map((item) => (
<Cell key={item}>{item}</Cell>
))
}
<List.Placeholder
onClick={() => {
if (error) {
setHasMore(true)
setError(false)
}
}}
>
{loading && <Loading>加载中...</Loading>}
{error && "请求失败,点击重新加载"}
{!hasMore && "没有更多了"}
</List.Placeholder>
</List>
)
}
List 组件可以与 PullRefresh 组件结合使用,实现下拉刷新的效果。
function PullRefreshList() {
const [hasMore, setHasMore] = useState(true)
const [list, setList] = useState<string[]>([])
const [loading, setLoading] = useState(false)
const refreshingRef = useRef(false)
const [scrollTop, setScrollTop] = useState(0)
const [reachTop, setReachTop] = useState(true)
usePageScroll(({ scrollTop: aScrollTop }) => {
setScrollTop(aScrollTop)
setReachTop(aScrollTop === 0)
})
const onLoad = () => {
setLoading(true)
const newList = refreshingRef.current ? [] : list
setTimeout(() => {
refreshingRef.current = false
for (let i = 0; i < 10; i++) {
const text = newList.length + 1
newList.push(text < 10 ? "0" + text : String(text))
}
setList(newList)
setLoading(false)
setHasMore(newList.length < 40)
}, 1000)
}
function onRefresh() {
refreshingRef.current = true
setLoading(false)
onLoad()
}
return (
<PullRefresh loading={refreshingRef.current} reachTop={reachTop} onRefresh={onRefresh}>
<List loading={loading} hasMore={hasMore} scrollTop={scrollTop} onLoad={onLoad}>
{
list.map((item) => (
<Cell key={item}>{item}</Cell>
))
}
{!refreshingRef.current && (
<List.Placeholder>
{loading && <Loading>加载中...</Loading>}
{!hasMore && "没有更多了"}
</List.Placeholder>
)}
</List>
</PullRefresh>
)
}
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
scrollTop | 距离顶部的滚动距离 | number | 0 |
loading | 是否处于加载状态,加载过程中不触发 onLoad 事件 |
boolean | ()=> boolean | false |
hasMore | 是否已加载完成,加载完成后不再触发 onLoad 事件 |
boolean | ()=> boolean | false |
offset | 滚动条与底部距离小于 offset 时触发 onLoad 事件 |
number | 300 |
direction | 滚动触发加载的方向,可选值为 up |
string | down |
组件提供了下列 CSS 变量,可用于自定义样式,使用方法请参考 ConfigProvider 组件。
名称 | 默认值 | 描述 |
---|---|---|
—list-text-color | var(—gray-6) | - |
—list-text-font-size | var(—font-size-md) | - |
—list-text-line-height | 50px * $hd | - |
—list-loading-icon-size | 16px * $hd | - |
—list-loading-icon-width | var(—list-loading-icon-size) | - |
—list-loading-icon-height | var(—list-loading-icon-size) | - |
如果一次请求加载的数据条数较少,导致列表内容无法铺满当前屏幕,List 会继续触发 load 事件,直到内容铺满屏幕或数据全部加载完成。因此你需要调整每次获取的数据条数,理想情况下每次请求获取的数据条数应能够填满一屏高度。
List
有以下三种状态,理解这些状态有助于你正确地使用 List
组件:
loading
为 false
,此时会根据列表滚动位置判断是否触发 onLoad
事件(列表内容不足一屏幕时,会直接触发)loading
为 true
,表示正在发送异步请求,此时不会触发 onLoad
事件hasMore
为 false
,此时不会触发 onLoad
事件在每次请求完毕后,需要手动将 loading
设置为 false
,表示加载结束
若 List 的内容使用了 float 布局,可以在容器上添加 taroify-clearfix
类名来清除浮动,使得 List 能正确判断元素位置
<List>
<View class="taroify-clearfix">
<View class="float-item" />
<View class="float-item" />
<View class="float-item" />
</View>
</List>