Reputation: 3
How to limit the quantity of View inside of a scrollview.
My component take too much time to render, because the map function renders too many views. I need to show only 10 views, and when scroll up, renders more 10.
I'm using react native, hooks and typescript.
Upvotes: 0
Views: 1430
Reputation: 3
I changed to Flatlist! But initialNumToRender is not working as expected.
The flatlist is rendering all 150 transactions, not only 15, and i have no idea what to do.
I'm running .map() from another array with all others transactions to create newMonths with only those transactions that i want to use data={newMonths}
.
let newMonths = [];
const createArrayMonth = histInfos.map(function (info) {
if (info.created_at.slice(5, 7) === month) {
newMonths = [info].concat(newMonths);
}
});
them, i created my component:
function Item({ value }: { value: any }) {
let createdDay = value.item.created_at.slice(8, 10);
let createdMonth = value.item.created_at.slice(5, 7);
let createdYear = value.item.created_at.slice(2, 4);
function dateSelected() {
if (
month === createdMonth &&
year === createdYear &&
(day === '00' || day == createdDay)
) {
console.log('foi dateSelected');
const [on, setOn] = useState(false);
const Details = (on: any) => {
if (on === true) {
return (
<View style={styles.infos}>
<Text style={styles.TextInfos}>
{' '}
CPF/CNPJ: {value.item.cpf_cnpj}{' '}
</Text>
<Text style={styles.TextInfos}>
{' '}
Criado em: {value.item.created_at}{' '}
</Text>
<Text style={styles.TextInfos}>
{' '}
Endereço da carteira: {value.item.address}{' '}
</Text>
<Text style={styles.TextInfos}> Valor: {value.item.amount}BTC </Text>
</View>
);
} else {
return <View />;
}
};
return (
<View>
<TouchableOpacity
style={styles.card}
onPress={() => setOn(oldState => !oldState)}>
<View style={styles.dateStyleView}>
<Text style={styles.dateStyle}>{createdDay}</Text>
</View>
<View style={styles.left}>
<Text style={styles.title}>Venda rápida</Text>
<Text style={styles.semiTitle}>
{
{
0: 'Pendente',
1: 'Aguardando conclusão',
2: 'Cancelado',
100: 'Completo',
}[value.item.status]
}
</Text>
</View>
<View style={styles.right2}>
<Text style={styles.price}>R$ {value.item.requested_value}</Text>
</View>
</TouchableOpacity>
<View>{Details(on)}</View>
</View>
);
}
}
return dateSelected();}
and i call it here
return (
<ScrollView>
...
<View style={styles.center}>
...
<View style={styles.middle2}>
...
<FlatList
extraData={[refresh, newMonths]}
data={newMonths}
renderItem={(item: any) => <Item value={item} />}
keyExtractor={(item, index) => index.toString()}
initialNumToRender={15}
/>
</View>
</View>
</ScrollView>);}
The scroll bar in the right, start to increase until renders all transactions from the data: App scroll bar
Upvotes: 0
Reputation: 4631
First of all, if you have a large number of list data don't use scrollview. Because initially, it loads all the data to scrollview component & it costs performance as well.
Use flatlist in react-native instead of scrollview & you can limit the number of items to render in the initially using initialNumToRender. When you reach the end of the scroll position you can call onEndReached method to load more data.
A sample will like this
import React, { Component } from "react";
import { View, Text, FlatList, ActivityIndicator } from "react-native";
import { List, ListItem, SearchBar } from "react-native-elements";
class FlatListDemo extends Component {
constructor(props) {
super(props);
this.state = {
loading: false,
data: [],
page: 1,
seed: 1,
error: null,
refreshing: false
};
}
componentDidMount() {
this.makeRemoteRequest();
}
makeRemoteRequest = () => {
const { page, seed } = this.state;
const url = `https://randomuser.me/api/?seed=${seed}&page=${page}&results=20`;
this.setState({ loading: true });
fetch(url)
.then(res => res.json())
.then(res => {
this.setState({
data: page === 1 ? res.results : [...this.state.data, ...res.results],
error: res.error || null,
loading: false,
refreshing: false
});
})
.catch(error => {
this.setState({ error, loading: false });
});
};
handleRefresh = () => {
this.setState(
{
page: 1,
seed: this.state.seed + 1,
refreshing: true
},
() => {
this.makeRemoteRequest();
}
);
};
handleLoadMore = () => {
this.setState(
{
page: this.state.page + 1
},
() => {
this.makeRemoteRequest();
}
);
};
renderSeparator = () => {
return (
<View
style={{
height: 1,
width: "86%",
backgroundColor: "#CED0CE",
marginLeft: "14%"
}}
/>
);
};
renderHeader = () => {
return <SearchBar placeholder="Type Here..." lightTheme round />;
};
renderFooter = () => {
if (!this.state.loading) return null;
return (
<View
style={{
paddingVertical: 20,
borderTopWidth: 1,
borderColor: "#CED0CE"
}}
>
<ActivityIndicator animating size="large" />
</View>
);
};
render() {
return (
<List containerStyle={{ borderTopWidth: 0, borderBottomWidth: 0 }}>
<FlatList
data={this.state.data}
renderItem={({ item }) => (
<ListItem
roundAvatar
title={`${item.name.first} ${item.name.last}`}
subtitle={item.email}
avatar={{ uri: item.picture.thumbnail }}
containerStyle={{ borderBottomWidth: 0 }}
/>
)}
keyExtractor={item => item.email}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
ListFooterComponent={this.renderFooter}
onRefresh={this.handleRefresh}
refreshing={this.state.refreshing}
onEndReached={this.handleLoadMore}
onEndReachedThreshold={50}
/>
</List>
);
}
}
export default FlatListDemo;
Check this for more informations.
Upvotes: 2