Maximum call stack size exceeded when using React Native Navigation

Oscar :


I have just started using React Native so I am still learning.
I am trying to implement Navigation to my app and almost everything works fine except for one page.
In the app, when the user signs up, he can sign up as either an individual or as an organization, which would lead him to different signing up forms depending on his choice.
However, when I select either option the app crashes and I get the following error:

Uncaught Error: RangeError: Maximum call stack size exceeded, stack.

I have looked online for answers and most of the time it's because there is an infinite loop in the navigation. However, I don't see anywhere in the code where there might be a loop and I did it as I did for the other pages, which, once again, work fine.

Here is the code for the App.js

import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { LinearGradient } from 'expo-linear-gradient';

import WelcomeToKarma from "./components/WelcomeToKarma.js";
import Login from "./components/Login.js";
import ForgotPass from "./components/ForgotPass.js";
import UserRegistration from "./components/UserRegistration.js";
import OpenEmail from "./components/OpenEmail.js";


function InitialScreen({ navigation }) {
  return (

    <View style={styles.container}>
      <LinearGradient
        style={{ alignItems: 'center', justifyContent: 'center', flex: 1, width: '100%' }}
        colors={['#00c5c4', '#01a7a6']}
        start={{ x: 1, y: 0 }}
        end={{ x: 0, y: 0 }}>
        <Text style={styles.textHeader}>KARMA</Text>
        <Text style={styles.text}>Lorem ipsum dolo ecte </Text>
        <Text style={styles.text}>adipisicing elit sed do</Text>
        <TouchableOpacity
          style={styles.buttonContainer}
          onPress={() => navigation.navigate('Back')}
        >
          <Text style={{ color: "white", fontSize: 20, }}>Sign Up</Text>
        </TouchableOpacity>
        <Text
          style={styles.loginText}
          onPress={() => navigation.navigate('Loginate')}
        >
          Already have an account? Login
            </Text>
      </LinearGradient>
    </View>
  );
}

const Stack = createStackNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={InitialScreen} options={{ headerShown: false }} />
        <Stack.Screen name="Back" component={WelcomeToKarma} options={{ headerShown: false }} />
        <Stack.Screen name="UserRegistration"
          component={UserRegistration}
          options={{
            headerTintColor: '#01b0b0',
            title: 'Sign up',
            headerTitleStyle: {
              textAlign: 'left',
              fontWeight: 'bold',
              fontSize: 22,
              color: 'black',
            }
          }} />
        <Stack.Screen name="Loginate" component={Login}
          options={{
            headerTintColor: '#01b0b0',
            title: 'Login',
            headerTitleStyle: {
              textAlign: 'left',
              color: 'black',
              fontSize: 22,
            }
          }} />
        <Stack.Screen name="ForgotPass" component={ForgotPass}
          options={{
            headerTintColor: '#01b0b0',
            title: 'Forgot Password',
            headerTitleStyle: {
              textAlign: 'left',
              color: 'black',
              fontSize: 22,
            }
          }} />
        <Stack.Screen name="OpenEmail" component={OpenEmail}
          options={{
            headerTintColor: '#01b0b0',
            title: "Forgot Password",
            headerTitleStyle: {
              textAlign: 'left',
              color: 'black',
              fontSize: 22,
            }
          }} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  textHeader: {
    color: 'white',
    fontSize: 80,
  },
  text: {
    color: 'white',
    fontSize: 20,
  },
  buttonContainer: {
    borderColor: 'white',
    borderWidth: 2,
    borderRadius: 30,
    alignItems: 'center',
    justifyContent: 'center',
    flexDirection: 'row',
    height: 44,
    width: 200,
    marginBottom: 20,
    marginTop: 10,
    position: 'absolute',
    bottom: 60,
  },
  loginText: {
    color: "white",
    fontSize: 15,
    marginTop: 10,
    marginBottom: 20,
    bottom: 10,
    position: 'absolute',
    justifyContent: 'center',
    alignItems: 'center'
  },
});

Here is the code for WelcomeToKarma.js which is where the user chooses if he is an individual or an organization.

import React, { Component } from 'react';
import { StyleSheet, Text, View, TouchableOpacity, ScrollView, SafeAreaView } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
import Constants from 'expo-constants';

import heart from '../assets/heart.png';
import earth from '../assets/earth.png';
import Card from './Card.js';


export default class WelcomeToKarma extends Component {
  render() {
    const { navigate } = this.props.navigation;
    return (
      <SafeAreaView style={{ flex: 1 }}>
        <View style={styles.container}>
          <View style={styles.welcomeText}>
            <Text style={styles.header}>Welcome to KARMA</Text>
            <Text style={styles.text}>Lorem ipsum dolo sit amet, consectetur adip isicing elit, sed do eiusmod</Text>
          </View>
          <ScrollView
            scrollEventThrottle={16}
            horizontal={true}
            showsHorizontalScrollIndicator={false}
            style={styles.scrollViewView}>
            <Card imageUri={heart} question="Are you an individual?" page="UserRegistration"></Card
{/* This is where the app crashes when I press the TouchableOpacity*/}
            <Card imageUri={earth} question="Are you an organization?" page=""></Card>
{/* And here as well, I know the page parameter is empty, that's because I still haven't done the page for it */}
          </ScrollView>
          <View style={styles.bottomView}>
            <Text style={styles.boldText}>Already on Karma?</Text>
            <View style={styles.buttonView}>
              <LinearGradient
                style={{ borderRadius: 22, alignItems: 'center', justifyContent: 'center', flexDirection: 'row' }}
                colors={['#00c5c4', '#01a7a6']}
                start={{ x: 1, y: 0 }}
                end={{ x: 0, y: 0 }}>
                <TouchableOpacity
                style={styles.loginButton}
                  onPress={() => navigate('Loginate')}
                >
                  <Text style={styles.login}>Login</Text>
                </TouchableOpacity>
              </LinearGradient>
            </View>
          </View>
        </View>
      </SafeAreaView>
    );
  }
}


const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#F5F5F5',
    marginTop: Constants.statusBarHeight,
    alignItems: 'center',
    justifyContent: 'center',
  },
  welcomeText: {
    marginBottom: 10,
  },
  scrollViewView: {
    alignItems: 'center',
    pagingEnabled: 'true',
    showPageIndicator: 'true',
    marginBottom: 20,
  },
  bottomView: {
    backgroundColor: 'white',
    width: '100%',
    marginHorizontal: 20,
    paddingBottom: 30,
  },
  buttonView: {
    backgroundColor: 'white',
    alignItems: 'center',
    width: '100%'
  },
  header: {
    fontSize: 20,
    marginHorizontal: 20,
    marginVertical: 10,
    textAlign: 'left'
  },
  text: {
    fontSize: 15,
    marginHorizontal: 20,
    marginVertical: 10,
    textAlign: 'left'
  },
  boldText: {
    fontSize: 15,
    marginHorizontal: 20,
    marginVertical: 10,
    textAlign: 'left',
    fontWeight: 'bold'
  },
  loginButton: {
    borderRadius: 22,
    alignItems: 'center',
    justifyContent: 'center',
    flexDirection: 'row',
    height: 44,
    width: '85%',
    padding: 20,
    backgroundColor: 'white',
    margin: 2,
  },
  login: {
    color: '#01b0b0',
    textAlign: 'center',
    fontSize: 20,
  },
});

I'm basically trying to pass the ToucheableOpacity onPress as a parameter to Card. The app crashes when I press these buttons.

And here is the code for the Card.js.

import React, { Component } from 'react';
import { StyleSheet, Text, View, TouchableOpacity, Image } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';

class Card extends Component {
    constructor(props) {
        super(props);
        this.navigate.bind(this);
    }

    navigate(txt) {
        this.navigate(txt);
    }

    render() {
        return (
            <View style={styles.container}>
                <View style={{ justifyContent: 'space-between', alignItems: 'center', flex: 1 }}>
                    <Image source={this.props.imageUri} style={{ width: '50%', height: '50%', resizeMode: 'cover' }}></Image>
                </View>
                <View style={{ justifyContent: 'center', flex: 1 }}>
                    <Text style={{ marginVertical: 5, fontWeight: 'bold' }}>{this.props.question}</Text>
                    <Text style={{ marginVertical: 5 }}>Lorem ipsum dolor sit amet, consectetur adip isicing elit,
                   sed do eiusm ut labore et dolore magna aliqua
                    </Text>
                    <View>
                        <LinearGradient
                            style={styles.signupButtonView}
                            colors={['#00c5c4', '#01a7a6']}
                            start={{ x: 1, y: 0 }}
                            end={{ x: 0, y: 0 }}
                        >
                            <TouchableOpacity
                                onPress={() => this.navigate(this.props.page)}>
                                <Text style={styles.signup} >Sign up</Text>
                            </TouchableOpacity>
                        </LinearGradient>
                    </View>
                </View>
            </View>
        )
    }
}

export default Card;

const styles = StyleSheet.create({
    container: {
        height: '95%',
        width: 250,
        borderRadius: 20,
        borderBottomWidth: 10,
        borderBottomColor: '#01b0b0',
        marginHorizontal: 10,
        marginVertical: 10,
        shadowColor: 'black',
        shadowOffset: { width: 0, height: 3 },
        shadowRadius: 6,
        shadowOpacity: 0.26,
        elevation: 8,
        padding: 20,
        backgroundColor: 'white'
    },
    signupButtonView: {
        borderRadius: 22,
        alignItems: 'center',
        justifyContent: 'center',
        flexDirection: 'row',
        padding: 20,
        height: 44,
        width: 200,
    },
    signupButton: {
        borderRadius: 22,
        alignItems: 'center',
        justifyContent: 'center',
        flexDirection: 'row',
        padding: 20,
        height: 44,
        width: 200,
    },
    signup: {
        color: 'white',
        fontSize: 20,
    },
    sty: {
        borderRadius: 30,
    }
});

The navigation works perfectly fine with every other page so I don't understand why it can't with this one. Could it be because I am not passing the ToucheableOpacity onPress method correctly? I have tried different ways to pass the onPress as a parameter but it looks like this way is the best way (if not the only?)
I'm also taking any tips and suggestions to improve my coding, as I said: I have just started learning React Native.

Michael Ceber :

This looks very recursive:

  navigate(txt) {
        this.navigate(txt);
   }

You have bound navigate to the class. You are inside the function navigate, and the line in there is calling itself. You will get a stackover.com

You need to pick up the navigate props in 'Card' like you did in 'WelcomeToKarma' and use this to navigate.

 const { navigate } = this.props.navigation;

so navigate could become

  navigate(txt) {
        this.props.navigate(txt);
    }

problem solved!

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=29953&siteId=1