SayYoungMan
SayYoungMan

Reputation: 33

What causes "RangeError: Maximum call stack size exceeded" in my code?

Hi Im trying to make my own login screen for my app and im getting this error.

It says the error is located at:

in Login (at App.js:12)

This is my Login.js:

import React, { Component } from "react";
import { View, Text } from "react-native";
import { Header, Card, CardSection, Input, Button, Spinner } from "../components";
import PasswordTextInput from "../components/PasswordTextInput";

class Login extends Component {
  state = { email: "", password: "", error: "", loading: false };

  onButtonPress() {
    const { email, password } = this.state;
    if (email.length === 0 || password.length === 0) {
      this.setState({
        error: "Please enter valid credential",
        loading: false
      })
    }
    else {
      this.setState({ error: "", loading: true });
    }
  }

  onLoginFail() {
    this.setState({
      error: "Authentication Failed",
      loading: false
    });
  }

  onLoginSuccess() {
    this.setState({
      email: "",
      password: "",
      loading: false,
      error: ""
    });
  }

  renderButton() {
    if (this.state.loading) {
      return <Spinner size="small" />;
    }

    return <Button onPress={this.onButtonPress.bind(this)}>Log in</Button>;
  }

  renderError() {
    if (this.state.error.length > 0) {
      return <Text style={styles.errorStyle}>{this.state.error}</Text>
    }
  }

  render() {
    return (
      <View>
        <Header title="Login" />

        <Card>
          <CardSection>
            <Input
              placeholder="Enter Email"
              label="Email"
              value={this.state.email}
              onChangeText={email => this.setState({ email })}
            />
          </CardSection>

          <CardSection>
            <PasswordTextInput
              placeholder="Enter Password"
              label="Password"
              value={this.state.password}
              onChangeText={password => this.setState({ password })}
            />
          </CardSection>

          {this.state.error.length > 0 && <Text style={styles.errorStyle}>{this.state.error}</Text>}

          <CardSection>{this.renderButton()}</CardSection>
        </Card>
      </View>
    );
  }
}

const styles = {
  errorStyle: {
    fontSize: 18,
    alignSelf: "center",
    color: "red",
    padding: 5
  }
};

export default Login;

And this is my App.js:

import React, { Component } from 'react';
import {
  AppRegistry
} from 'react-native';

import Login from './src/pages/Login';

export default class App extends Component {

  render() {
    return (
      <Login />
    );
  }

}

AppRegistry.registerComponent('App', () => App);

I have read about some of the solutions regarding this similar problems and it was said that I am calling a function that calls the another function and back and forth thus it hits the limit.

Maximum call stack size exceeded error

Could you go through my code and tell me what change I have to make to the Login.js file?

Upvotes: 1

Views: 5682

Answers (2)

IvanAllue
IvanAllue

Reputation: 555

I'm going to throw a triple, to see if it enters:

The problem I think you have is the following: In the Input and in the PasswordTextInput you have written incorrectly in the onChangeText method. This works but apart from doing it when the text is modified it is also executed as soon as the component is rendered.

Apart from that every time the text is changed, the state is modified (that's fine) but whenever the state is changed, the render method is executed. Since the tag has a value method that gives it value every time the render method is executed, the value is changed causing the onChangeText method to be executed by changing the state again and from there comes your problem.

As soon as the render method is executed, the onChangeText is executed as soon as you start, the error will appear.

Solution: Change your inputs to:

<Input
        placeholder="Enter Email"
        label="Email"
        onChangeText={(email) => {
          this.setState({ email })
        }}
      />


 <PasswordTextInput
        placeholder="Enter Password"
        label="Password"
        onChangeText={(password) => {
          this.setState({ password })
        }}
      />

Good luck ^^

Upvotes: 1

Ben
Ben

Reputation: 104

Please see https://stackoverflow.com/a/6095695/5393314

"It means that somewhere in your code, you are calling a function which in turn calls another function and so forth, until you hit the call stack limit.

This is almost always because of a recursive function with a base case that isn't being met."

So if you would try to break functions in small portions to verify that the stack doesn't get exceeded no more at a certain point in your code.

Upvotes: 1

Related Questions