Estevan Wisoczynski
Estevan Wisoczynski

Reputation: 3

Show View when scroll up Scrollview

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

Answers (2)

Estevan Wisoczynski
Estevan Wisoczynski

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

SDushan
SDushan

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

Related Questions