在本节中,我们将为首页列表添加上拉加载更多和下拉刷新功能。
一、下拉刷新功能
1. 配置 FlatList 属性
在 pages/Home/index.tsx 中,为 FlatList 添加 refreshing 和 onRefresh 属性:
<FlatList
refreshing={refreshing}
onRefresh={onRefresh}
data={channelList}
renderItem={renderItem}
keyExtractor={(item) => item.id}
onEndReached={onEndReached}
onEndReachedThreshold={0.2}
ListFooterComponent={renderFooter}
ListEmptyComponent={renderEmpty}
/>
2. 实现 onRefresh 方法
在组件中声明一个 refreshing 属性,并在 onRefresh 方法中调用数据请求:
interface IState {
refreshing: boolean;
}
class Home extends React.Component<IProps, IState> {
state = {
refreshing: false,
};
onRefresh = () => {
this.setState({
refreshing: true,
});
const { dispatch } = this.props;
dispatch({
type: 'home/fetchChannels',
callback: () => {
this.setState({
refreshing: false,
});
},
});
};
}
3. 更新 Model
在 models/home.ts 中,为 fetchChannels 方法添加回调:
*fetchChannels({ payload, callback }, { call, put, select }) {
const { data } = yield call(axios.get, CHANNEL_URL, {
params: payload,
});
const newChannels = data.results;
if (payload && payload.loadMore) {
const channels = yield select(({ home }: RootState) => home.channels);
newChannels = channels.concat(newChannels);
}
yield put({
type: 'setState',
payload: {
channels: newChannels,
pagination: {
current: data.pagination.current,
total: data.pagination.total,
hasMore: data.pagination.hasMore,
},
},
});
if (typeof callback === 'function') {
callback();
}
},
二、上拉加载更多功能
1. 配置 onEndReached 属性
在 FlatList 中添加 onEndReached 和 onEndReachedThreshold 属性:
onEndReachedThreshold={0.2}
onEndReached={this.onEndReached}
2. 实现 onEndReached 方法
在 Home 组件中声明 onEndReached 方法:
onEndReached = () => {
const { dispatch, hasMore, loading } = this.props;
if (loading || !hasMore) return;
dispatch({
type: 'home/fetchChannels',
payload: {
loadMore: true,
},
});
};
3. 更新 Model
在 models/home.ts 中,为 fetchChannels 方法添加分页逻辑:
*fetchChannels({ payload }, { call, put, select }) {
const { pagination } = yield select(({ home }: RootState) => home);
let currentPage = 1;
if (payload && payload.loadMore) {
currentPage = pagination.current + 1;
}
const { data } = yield call(axios.get, CHANNEL_URL, {
params: {
page: currentPage,
},
});
const newChannels = data.results;
if (payload && payload.loadMore) {
const channels = yield select(({ home }: RootState) => home.channels);
newChannels = channels.concat(newChannels);
currentPage = data.pagination.current;
}
yield put({
type: 'setState',
payload: {
channels: newChannels,
pagination: {
current: currentPage,
total: data.pagination.total,
hasMore: newChannels.length < data.pagination.total,
},
},
});
},
三、尾部和空列表处理
1. 渲染尾部组件
添加 ListFooterComponent 和 ListEmptyComponent 属性:
ListFooterComponent={this.renderFooter}
ListEmptyComponent={this.renderEmpty}
2. 实现 renderFooter 和 renderEmpty
renderFooter = () => {
const { hasMore, loading } = this.props;
if (!hasMore) {
return (
<View style={styles.end}>
<Text>我是有底线的</Text>
</View>
);
}
if (loading && hasMore) {
return (
<View style={styles.loading}>
<Text>正在加载中...</Text>
</View>
);
}
return null;
};
renderEmpty = () => {
const { loading } = this.props;
if (!loading) {
return (
<View style={styles.empty}>
<Text>暂无数据</Text>
</View>
);
}
return null;
};
3. 定义样式
const styles = StyleSheet.create({
end: {
alignItems: 'center',
paddingVertical: 10,
},
loading: {
alignItems: 'center',
paddingVertical: 10,
},
empty: {
alignItems: 'center',
paddingVertical: 100,
},
});
四、总结
在本节中,我们为首页列表添加了上拉加载更多和下拉刷新功能。通过配置 FlatList 的属性和实现相应的逻辑,用户可以流畅地加载更多数据和刷新列表。下一节,我们将继续完善首页的功能。