0

I am having difficulty with a React component that contains a function that is to be called once upon initially rendering the component, and again when certain buttons are pressed within a child component (of which the function is passed to via props).

At the moment, upon loading the component, the function seems to be endlessly called, eventually causing the app to crash.

Here is a simplified example of the code:

    import React, { Component } from "react";
import { Text, View } from "react-native";
import { loadEntries } from "./functions/loadEntries";

export default class StackOverflow extends Component {
  constructor(props) {
    super(props);

    this.state = {
      truthyFalsy: false,
    };
  }

  setTrueOrFalse = async () => {
    const textEntry = await loadEntries(entryType);
    if (textEntry.length === 0) {
      await this.setState({ truthyFalsy: false });
    } else if (textEntry.length > 0) {
      await this.setState({ truthyFalse: true });
    }
  };

  componentDidMount() {
    this.setTrueOrFalse();
  }

  render() {
    return (
      <View>
        {this.state.truthyFalsy ? (
          <True />
        ) : (
          <False setTrue={this.setTrueOrFalse()} />
        )}
      </View>
    );
  }
}

Any help would be greatly appreciated!

EDIT:

T.J's solution has solved for some of the looping issues, however it appears that was not the only function looping in my code. Below I have included some more context on the True component within which the mapStateToProps function is also infinitely looping.

import React, { Component } from "react";
import { Text, View } from "react-native";
import { loadEntries } from "./functions/loadEntries";

export default class StackOverflow extends Component {
  constructor(props) {
    super(props);

    this.state = {
      truthyFalsy: false,
    };
  }

  setTrueOrFalse = async () => {
    const textEntry = await loadEntries(entryType);
    if (textEntry.length === 0) {
      await this.setState({ truthyFalsy: false });
    } else if (textEntry.length > 0) {
      await this.setState({ truthyFalse: true });
    }
  };

  componentDidMount() {
    this.setTrueOrFalse();
  }

  render() {
    return (
      <View>
        {this.state.truthyFalsy ? (
          <True users={this.props.users} userId={this.props.userId} />
        ) : (
          <False setTrue={this.setTrueOrFalse} />
        )}
      </View>
    );
  }
}

const mapStateToProps = (state) => {
    let entries = state.users.entries || [];
    return {
      entries,
    };
  };
  
  
  export default connect(
    mapStateToProps,
  )(StackOverflow);

class True extends Component {
  constructor(props) {
    super(props);
    this.state = {
    };
  }
  renderEntries(userId) {
    let user = this.props.users.filter((user) => user.userId === userId)[0];
    if (!user) {
      user = { entry: 0, userId: userId };
    }
    return <Text>{user.entry}</Text>;
  }

  render() {
    return (
        <View>
            {this.renderEntries(this.props.userId)}
        </View>
            )
        }
}
GrapeJam
  • 181
  • 14
  • 1
    The problem is the `()` on ``, which shouldn't be there. – T.J. Crowder Oct 21 '20 at 09:47
  • 2
    Side note: `setState` doesn't return a promise, so there's no point using `await` with it. Also note you don't have anything handling rejection of the promise `setTrueOrFalse` returns. – T.J. Crowder Oct 21 '20 at 09:47
  • Thank you @T.J.Crowder - your solution appears to have plugged that particular loop. Unfortunately I have now discovered that there is another loop occurring in the code which seems to be within the `mapStateToProps` function of the `True` child component. I have edited my code to provide more context. and thank you for pointing out the lack of rejection handling! I will make sure to fix that :) – GrapeJam Oct 21 '20 at 10:46

0 Answers0