Добавить в FlatList кнопку "подробнее"?
Я использую flatList для составления списка элементов. Я хотел бы показать 15 элементов, а затем добавить кнопку "увидеть больше", чтобы показать следующие 15 и т. Д. Я собирался использовать этот учебник: https://aboutreact.com/react-native-flatlist-pagination-to-load-more-data-dynamically-infinite-list/ Но мне не нужно использовать выборку, я уже настроил данные (state.listData), и на самом деле я немного не понимаю, как их адаптировать...
Я подумал, что, может быть, кто-нибудь сможет мне немного помочь. большое спасибо
this.state = {
selectedId: '',
setSelectedId:'',
listData:''
}
};
renderItem = ({ item }) => {
const backgroundColor = item.id === this.selectedId ? "transparent" : "fff";
return (
<View style={{flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center'}}>
<Item
item={item}
onPress={() => this.props.navigation.navigate('UpdateTripsForm')}
style={{ backgroundColor }}
/>
<Image source={require("../../assets/images/arrow.png")} style={{width: 15, height:15, justifyContent: 'center'}}/>
</View>
);
};
initListData = async () => {
let list = await getFlights(0);
if (list) {
this.setState({
listData: list
});
}
};
render() {
return (
<SafeAreaView style={styles.container}>
<FlatList
data={this.state.listData}
renderItem={this.renderItem}
maxToRenderPerBatch={15}
keyExtractor={(item) => item.id}
extraData={this.selectedId}
/>
<TouchableOpacity
style={styles.touchable2}
onPress={() => this.props.navigation.goBack()}
>
<View style={styles.view2}>
<Text style={styles.textimg2}>
{i18n.t("tripsform.action.back")}
</Text>
</View>
<Image
source={require("../../assets/images/btn-background.png")}
style={styles.tripsimg2}
/>
</TouchableOpacity>
</SafeAreaView>
);
};
}
Я просто попробовал это благодаря ответу @Pramod:
const Item = ({ item, onPress, style }) => (
<TouchableOpacity onPress={onPress} style={[styles.flightsListitem, style]}>
<Text style={styles.h4}>{item.id}</Text>
</TouchableOpacity>
);
export default class FlightsList extends Component {
constructor(props) {
super(props);
this.state = {
selectedId: '',
setSelectedId:'',
listData:'',
page:1,
perPage:2,
loadMoreVisible:true,
displayArray:[]
}
};
renderItem = ({ item }) => {
const backgroundColor = item.id === this.selectedId ? "transparent" : "fff";
return (
<View style={{flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center'}}>
<Item
item={item}
onPress={() => this.props.navigation.navigate('UpdateTripsForm')}
style={{ backgroundColor }}
/>
<Image source={require("../../assets/images/arrow.png")} style={{width: 15, height:15, justifyContent: 'center'}}/>
</View>
);
};
initListData = async () => {
let list = await getFlights(0);
if (list) {
this.setState({
listData: list
});
}
};
componentDidMount(){
this.setNewData()
// console.log(tempArray)
}
setNewData(){
var tempArray=[]
if(this.state.listData.length == this.state.displayArray.length){
this.setState({
loadMoreVisible:false
})
}else{
for(var i=0; i<(this.state.page*this.state.perPage); i++){
tempArray.push(this.state.listData)
}
this.setState({
displayArray: tempArray,
loadMoreVisible:true
})
}
}
loadMore(){
this.setState({
page: this.state.page+1
},()=>{
this.setNewData()
})
}
async UNSAFE_componentWillMount() {
this.initListData();
}
render() {
return (
<ImageBackground
source={require("../../assets/images/background.jpg")}
style={styles.backgroundImage}
>
<Header
backgroundImage={require("../../assets/images/bg-header.png")}
backgroundImageStyle={{
resizeMode: "stretch",
}}
centerComponent={{
text: i18n.t("mytrips.title"),
style: styles.headerComponentStyle,
}}
containerStyle={[styles.headerContainerStyle, { marginBottom: 0 }]}
statusBarProps={{ barStyle: "light-content" }}
/>
<SafeAreaView style={styles.container}>
<FlatList
data={this.state.displayArray}
renderItem={this.renderItem}
keyExtractor={(item) => item.id}
extraData={this.selectedId}
/>
{this.state.loadMoreVisible == true?
<Button style={{width:'100%', height:10, backgroundColor:'green', justifyContent:'center', alignItems:'center'}}
title = 'load more'
onPress={()=>{this.loadMore()}}>
</Button>:null}
<TouchableOpacity
style={styles.touchable2}
onPress={() => this.props.navigation.goBack()}
>
<View style={styles.view2}>
<Text style={styles.textimg2}>
{i18n.t("tripsform.action.back")}
</Text>
</View>
<Image
source={require("../../assets/images/btn-background.png")}
style={styles.tripsimg2}
/>
</TouchableOpacity>
</SafeAreaView>
</ImageBackground>
);
};
}
2 ответа
Вы можете использовать метод разбивки на страницы с ограничением на страницу, чтобы вы могли иметь детальный контроль
- Загружать массив на страницу при монтировании компонента
- При каждом клике увеличивайте на странице и на основе данных обновления страницы вашего плоского списка
- А также установите флаг, который будет проверять, когда данные закончились, что поможет скрыть кнопку загрузки больше, когда данные закончились
Рабочий пример: https://snack.expo.io/@msbot01/suspicious-orange
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
SafeAreaView,
SectionList,
Switch,
FlatList
} from 'react-native';
import Constants from 'expo-constants';
import Icon from 'react-native-vector-icons/FontAwesome';
import AwesomeIcon from 'react-native-vector-icons/FontAwesome';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
export default class App extends Component<Props> {
constructor(props) {
super(props);
this.state = {
page:1,
perPage:2,
loadMoreVisible:true,
DATA: [{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'fourth Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'fifth Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29sd72',
title: 'sixth Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29dr72',
title: 'seventh Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d7w2',
title: 'Eight Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29ad72',
title: 'Nineth Item',
},
{
id: '58694a0f-3da1-471f-bd96-14557d1e29d72',
title: 'Tenth Item',
}],
displayArray:[]
}
}
componentDidMount(){
this.setNewData()
// console.log(tempArray)
}
setNewData(){
var tempArray=[]
if(this.state.DATA.length == this.state.displayArray.length){
this.setState({
loadMoreVisible:false
})
}else{
for(var i=0; i<(this.state.page*this.state.perPage); i++){
tempArray.push(this.state.DATA[i])
}
this.setState({
displayArray: tempArray,
loadMoreVisible:true
})
}
}
loadMore(){
this.setState({
page: this.state.page+1
},()=>{
this.setNewData()
})
}
render() {
return (
<View style={{ flex: 1 }}>
<FlatList
data={this.state.displayArray}
renderItem={({item})=>
<View style={{flexDirection:'row'}}>
<Text style={{fontSize:20}}>{item.title} </Text>
</View>
}
keyExtractor={item => item.id}
/>
{this.state.loadMoreVisible == true?
<View style={{width:'100%', height:10, backgroundColor:'green', justifyContent:'center', alignItems:'center'}} onClick={()=>{this.loadMore()}}>Load more</View>:null
}
</View>
);
}
}
- Установить данные в состояние (уже сделано ==> this.state.listData)
- Установить счетчик в состояние (инициализировать с 1)
- Установите 15 первых элементов в состояние (вы можете назвать это "renderedData" или что-то в этом роде), а затем увеличьте cuonter до 1
- Добавьте функцию, которая увеличивает "renderedData" на 15 элементов, увеличивая счетчик на единицу.
- Добавьте в список компонент Footer, который будет вызывать функцию, созданную на этапе 3.
Чтобы взять только 15(или 30/45/60 и т. Д.) Предметов из списка, вы можете сделать что-то вроде этого:
this.setState({ renderedItem: listData.slice(0, counter*15) })