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)
return (
<List
loading={loading}
hasMore={hasMore}
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>
)
}
Tips: 在 Tabs 里使用,通过设置 disabled={tabKey !== activeTabKey},避免其他 tab 里的 List 也触发了滑动
设置 fixedHeight,通过 class 或者 style 指定容器高度
function FixedHeightList() {
const [hasMore, setHasMore] = useState(true)
const [list, setList] = useState<string[]>([])
const [loading, setLoading] = useState(false)
const ref = useRef<ListInstance>(null)
return (
<>
<List
ref={ref}
loading={loading}
hasMore={hasMore}
fixedHeight
style={{ height: "300px" }}
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)
return (
<List
loading={loading}
hasMore={hasMore}
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 && "请求失败,点击重新加载"}
{!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 [reachTop, setReachTop] = useState(true)
usePageScroll(({ scrollTop: 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} onLoad={onLoad}>
{list.map((item) => (
<Cell key={item}>{item}</Cell>
))}
{!refreshingRef.current && (
<List.Placeholder>
{loading && <Loading>加载中...</Loading>}
{!hasMore && "没有更多了"}
</List.Placeholder>
)}
</List>
</PullRefresh>
)
}
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
fixedHeight v0.1.1-alpha.2 | 是否固定高度 | boolean | false |
loading | 是否处于加载状态,加载过程中不触发 onLoad 事件 | boolean | false |
hasMore | 是否已加载完成,加载完成后不再触发 onLoad 事件 | boolean | false |
offset | 滚动条与底部距离小于 offset 时触发 onLoad 事件 | number | 100 |
immediateCheck v0.1.1-alpha.2 | 是否在初始化时立即执行滚动位置检查 | boolean | true |
disabled v0.1.1-alpha.2 | 是否禁用滚动加载 | boolean | false |
direction | 滚动触发加载的方向,可选值为 up | string | down |
v0.1.1-alpha.2 移除 | 距离顶部的滚动距离 | number | 0 |
组件提供了下列 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) | - |
offset
时,List 会触发一次 load 事件。如果一次请求加载的数据条数较少,导致列表内容无法铺满当前屏幕,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>