Sanduni Fernando
Sanduni Fernando

Reputation: 33

How to resolve Error " Too many re-renders. React limits the number of renders to prevent an infinite loop." in react native?

I have develop form to submit complaint by selecting product prom picker. So I externally implement the picker and then use it in complaint submission form. For that I was needed to take selectedValue state into complaint submission form by using function handle change. After i implement that faction and change appropriate places regarding to the tutorial link : [https://github.com/reactjs/reactjs.org/issues/1689][1]

But when I navigate to the complaint submission form it says the error as " Error: Too many re-renders. React limits the number of renders to prevent an infinite loop."So help me to resove and please confirm am I follow the above tutorial correctly.

Complaint submission form:

import * as React from 'react';
import {Button, View, Text, ScrollView, StyleSheet, Alert} from 'react-native';
import {Appbar} from 'react-native-paper';
import {TextInput, HelperText} from 'react-native-paper';
import {useEffect, useState} from 'react';
import AsyncStorage from '@react-native-community/async-storage';
import ProductPicker from './ProductPicker';

const ComplaintSubmission = ({navigation}) => {

    const [productID , setproductID] = useState('');
    const [description , setdescription] = useState('');
    const [token, setToken] = useState('');


    useEffect(() => {
        saveToken();

    }, []);

function handleChange(newValue){
    setproductID(newValue);
}

    const saveToken = async () => {
        const token = await AsyncStorage.getItem('userToken');
        console.log('token from storage', token);
        setToken(token);
    }

    const send = () =>{

        fetch("http://10.0.2.2:3000/customer/lodge-complaint", {

            method: "post",
            headers: {
                'Content-Type': 'application/json',
                'Authentication': `Bearer ${token}`
            },
            body: JSON.stringify({

                description : description,
                productID : value

            })

        })

    }

    const openAlert = () => {
        Alert.alert(
            "Complaint Successfully Submitted",
            "We review it as soon as possible. Thank you for reaching for us!",
            [{
                text: "OK",
                onPress : () => navigation.navigate("DashboardDrawer" ),
            }]
        );
    }

  return (
    <ScrollView>

      <Appbar.Header>
        <Appbar.BackAction onPress={() => navigation.goBack()} />
        <Appbar.Content title="Submit Complaint" />
        <Appbar.Action icon="magnify" onPress={() => navigation.openDrawer()} />
      </Appbar.Header>

      <Text>Plese Fill the following</Text>

      <View>
          {/*{console.log('renderer token', token)}*/}
       <ProductPicker value={productID} onValueChange = {handleChange()} />
        <HelperText type="info">
          Make sure select the correct Product
        </HelperText>
      </View>

      <TextInput
        style={styles.PIDstyle}
        label="Description"
        onChangeText = {(description) => setdescription(description)}
      />
      <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
        <Text>This is submittion</Text>
        <Button onPress={() => {send(); openAlert();}} title="Submit Complaint" />
      </View>
    </ScrollView>
  );
};
export default ComplaintSubmission;
const styles = StyleSheet.create({
  PIDstyle: {
    marginTop: 30,
    marginLeft: 10,
    marginRight: 10,
  },
});

And this is the picker component:

import React, {useEffect, useState} from 'react';
import {View, StyleSheet} from 'react-native';
import {Picker} from '@react-native-picker/picker';
import AsyncStorage from '@react-native-community/async-storage';


const ProductPicker = () => {
    const [selectedValue, setSelectedValue] = useState('');
    const [productDetails, setproductDetails] = useState([]);
console.log('product id---', selectedValue);



    useEffect(() => {
        getProductList();
    }, []);

    function handleChange(event){
        props.onValueChange(event.target.value);
    }

    const getProductList = async () => {
        const token = await AsyncStorage.getItem('userToken');
        console.log(' function eka athule------', token);

        fetch('http://10.0.2.2:3000/customer/get-all-products', {

            method: 'post',
            headers: {
                'Content-Type': 'application/json',
                'Authentication': `Bearer ${token}`,
            },
        })
            .then((response) => response.json())
            .then((json) => setproductDetails(json.data))
            .catch((error) => console.error(error));
    };

    return (

        <View style={styles.container}>
            <Picker
                selectedValue={selectedValue}
                style={{height: 40, width: 150}}
                onValueChange={(itemValue, itemIndex) => {
                    setSelectedValue(itemValue);
                    handleChange();
                }}

            >


                {productDetails.map((item, index) => {
                    return (
                        <Picker.Item label={item.productName} value={props.item.productID} key={index}/>);

                })}

            </Picker>

        </View>

    );

};

const styles = StyleSheet.create({
    container: {
        flex: 1,
        paddingTop: 40,
        alignItems: 'center',
    },
});

export default ProductPicker;

Upvotes: 0

Views: 139

Answers (1)

Taufan
Taufan

Reputation: 124

Why don't you pass the itemValue to handleChange?

onValueChange={(itemValue, itemIndex) => {
                    setSelectedValue(itemValue);
                    handleChange(itemValue);
                }}

Then change the function:

function handleChange(value){
        props.onValueChange(value);
    }

Upvotes: 1

Related Questions