Quantcast
Channel: Active questions tagged react-native+typescript - Stack Overflow
Viewing all articles
Browse latest Browse all 6211

How to execute a function when some item renders in react native?

$
0
0

I have a sectionlist of Contacts where I am displaying both device and online contacts of a user. The online contacts api doesnt give me all the contacts at once. So I have to implement some pagination. I am also fetching all device contacts and first page of online contacts and sorting them to show in sectionlist, but the problem is, to load more contacts, i have to keep track of the last item rendered in my state and in the render function I am calling pagination function to load more contacts. and then i am updating the state of fetched online contact. But its an unsafe operation, is there a better way to achieve this?

I want to execute a function when the specific item renders and it can update the state.

Here is some code: ContactList.tsx

import React, { Component } from "react";
import {
    View,
    StyleSheet,
    SectionListData,
    SectionList,
    Text
} from "react-native";

import { Contact } from "../../models/contact";
import ContactItem from "./contact-item";

export interface ContactsProps {
    onlineContacts: Contact[];
    deviceContacts: Contact[];
    fetchMoreITPContacts: () => void;
}

export interface ContactsState {
    loading: boolean;
    error: Error | null;
    data: SectionListData<Contact>[];
    lastItem: Contact;
    selectedItems: [];
    selectableList: boolean;
}

class ContactList extends Component<ContactsProps, ContactsState> {
    private sectionNames = [];

    constructor(props: ContactsProps, state: ContactsState) {
        super(props, state);
        this.state = {
            loading: false,
            error: null,
            data: [],
            lastItem: this.props.onlineContacts[this.props.onlineContacts.length - 1]
        };
        for (var i = 65; i < 91; ++i) {
            this.sectionNames.push({
                title: String.fromCharCode(i),
                data: []
            });
        }
    }

    private buildSectionData = contacts => {
        this.sort(contacts);
        const data = [];
        const contactData = this.sectionNames;
        contacts.map(contact => {
            const index = contact.name.charAt(0).toUpperCase();
            if (!data[index]) {
                data[index] = [];
                contactData.push({
                    title: index,
                    data: []
                })
            }
            data[index].push(contact);
        });
        for (const index in data) {
            const idx = contactData.findIndex(x => x.title === index);
            contactData[idx].data.push(...data[index]);
        }
        this.setState({
            loading: false,
            error: null,
            lastItem: contacts[contacts.length - 1],
            data: [...contactData]
        });
    };

    private sort(contacts) {
        contacts.sort((a, b) => {
            if (a.name > b.name) {
                return 1;
            }
            if (b.name > a.name) {
                return -1;
            }
            return 0;
        });
    }

    componentDidMount() {
        const contacts = [].concat(
            this.props.deviceContacts,
            this.props.onlineContacts
        );
        this.buildSectionData(contacts);
    }

    componentDidUpdate(
        prevProps: Readonly<ContactsProps>,
        prevState: Readonly<ContactsState>,
        snapshot?: any
    ): void {
        if (this.props.onlineContacts !== prevProps.onlineContacts) {
            const from = this.props.itpContacts.slice(
                prevProps.onlineContacts.length,
                this.props.onlineContacts.length
            );
            this.buildSectionData(from);
        }
    }

    renderItem(item: any) {
        if (!!this.state.lastItem && !this.state.loading)
            if (item.item.id === this.state.lastItem.id) {
                this.setState({
                    loading: true
                });
                this.props.fetchMoreOnlineContacts();
            }
        return <ContactItem item={item.item} />;
    }

    render() {
        return (
            <View style={styles.container}>
                <SectionList
                    sections={this.state.data}
                    keyExtractor={(item, index) => item.id}
                    renderItem={this.renderItem.bind(this)}
                    renderSectionHeader={({ section }) =>
                        section.data.length > 0 ? (
                            <Text style={styles.sectionTitle}>
                                {section.title}
                            </Text>
                        ) : null
                    }
                />
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1
    },
    sectionTitle: {
        paddingBottom: 30,

        paddingLeft: 25,
        fontWeight: "bold",
        fontSize: 20
    }
});

export default ContactList;


Viewing all articles
Browse latest Browse all 6211

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>