Home > OS >  Trying to come out with a filter function for my app. Render Error: Too many re-renders. React limit
Trying to come out with a filter function for my app. Render Error: Too many re-renders. React limit

Time:06-26

The idea I have for this to work is to copy my main array from firebase (Array with all my info) into a temporary array. Then I will filter this temporary array and have it displayed in flatlist. The onPress for the buttons serves to select the type of information to be filtered (Eg type 1 or 2 or 3).

import React, { useState, setState, useEffect } from 'react';
import { View, Text, StyleSheet, ImageBackground, FlatList, Button, TouchableHighlight } from 'react-native'
import Card from '../components/Card';
import colors from '../config/colors';
import {MaterialCommunityIcons} from '@expo/vector-icons'
import { useNavigation } from '@react-navigation/core';
import AppButton from '../components/AppButton'
import { SearchBar } from 'react-native-screens';

import { Firestore, getDoc, collection, getDocs,
        addDoc, deleteDoc, doc,
        query, where, onSnapshot
      
} from 'firebase/firestore';



import {db} from '../../firebase';
import { async } from '@firebase/util';

//run: 1
//swim: 2
//cycle: 3

function EventsPage(props) {
    

    const [events, setEvents] = useState([]);
    const [bool, setBool] = useState(false);
    const [arr, setArr] = useState([])
    const colRef = collection(db, 'events');
    
    
    const q = query(colRef, where('type', '>=', 0))

    onSnapshot(q, (snapshot) => {
        const events = []
        snapshot.docs.forEach((doc) => {
            events.push({...doc.data()}) //put the data into an array
        })
        if (bool === false) {
            setEvents(events);
            setBool(true)
        }
    })

    const updateSearch = search => {
        setArr({ search }, () => {
            if (type == search) {
                setArr({
                    data: [...arr.temp]
                });
                return;
            }
             
            arr.data = arr.temp.filter(function(item){
                return item.name.includes(search);
              }).map(function({date, subTitle, title, type}){
                return {date, subTitle, title, type};
            });
        });
    };
   

    return (

        <View style = {styles.container}>
            <ImageBackground
                source = {require('../assets/splash-page.jpg')}
                style = {{width: '100%', height: '100%'}}
                blurRadius={8}
            >   
            <View style = {styles.backIcon}>
                <MaterialCommunityIcons name='arrow-left-bold' color="black" size={35} onPress={() => {
                        navigation.replace("Connect_me")
                  }} />
            </View>
            
        <Text style = {styles.text}>EVENTS</Text>
        <View style = {styles.buttons}>
            <Button title={'All'} />
            <Button title={'Run'} onPress = {updateSearch(1)}/>
            <Button title={'Swim'} onPress = {updateSearch(2)}/>
            <Button title={'Cycle'} onPress = {updateSearch(3)}/>
        </View>
        <FlatList
            data={arr.data}
            renderItem={({ item }) => (
                <View style = {styles.cardContainer}>
                    <Card title={item.title} subTitle = {item.subTitle}/>
                </View>
            )}
            />
            
            <Text></Text>
            <Text></Text>
            <Text></Text>
            <Text></Text> 
            <Text></Text>
            
            </ImageBackground>
        </View>
        // trolling
    );
}

const styles = StyleSheet.create({
    text: {
        fontSize: 80,
        textAlign:'center',
        paddingBottom: 20,
        color: colors.primary,
        fontWeight: 'bold',
    },
    container: {
        backgroundColor: 'white',
    },
    cardContainer: {
        width: '95%',
        alignSelf: 'center'
    },
    backIcon: {
        paddingLeft: 10,
        paddingTop: 30,
    }, 
    searchIcon: {
        paddingLeft: 10,
        paddingTop: 15,
        position: 'relative',
        left: 330,
        bottom: 47
    },
    buttons: {
        flexDirection: 'row',
        padding: 20,
    }
})

export default EventsPage;

CodePudding user response:

Side effects code like listening to data change events should be handled inside the useEffect hook.

The app continues to listen to data change events for each component re-render which causes an infinity loop.

useEffect(() => {
  const unsubscribe = onSnapshot(q, (snapshot) => {
    const events = [];
    snapshot.docs.forEach((doc) => {
      events.push({ ...doc.data() }); //put the data into an array
    });
    if (bool === false) {
      setEvents(events);
      setBool(true);
    }
  });

  // unsubscribe to data change events when component unmount
  return () => {
    unsubscribe();
  };
}, []);



  • Related