Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJs app crashes with error "Consider adding error boundaries to your tree"

Trying to Build Random quote api app with React. When first time app loads on Button Click it generates the random quote. But on Second Click App Crashes with "Error occured in App Component" "Consider adding an error boundary to your tree to customize error handling behavior.

class App extends React.Component {
  state = {
    quotes: null
  };
  componentDidMount() {
  fetch("https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json")
      .then(res => res.json())
      .then(data => {
        // console.log(data);
        this.setState({
          quotes: data.quotes
        });
      });
    // console.log(this.state.quotes);
  }
  randomQuoteHandler = () => {
    const randNumb = Math.floor(Math.random() * this.state.quotes.length);
    const randomQuote = this.state.quotes[randNumb];
    this.setState({
      quotes: randomQuote
    });
    console.log(this.state.quotes);
  };
  render() {
    return (
      <div>
        <button onClick={this.randomQuoteHandler}>gen</button>
        <p>{this.state.quotes !== null && this.state.quotes.quote}</p>
        <p> {this.state.quotes !== null && this.state.quotes.author}</p>
      </div>
    );
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
like image 735
Aniket Avatar asked Apr 23 '19 11:04

Aniket


People also ask

Why are there error boundaries in react?

Reason to Use: Suppose there is an error in JavaScript inside component then it used to corrupt React's internal state and cause it to emit cryptic errors. Error boundaries help in removing these errors and display a Fallback UI instead(Which means a display of an error that something broke in the code).

How many error boundaries can we create and use in react?

Error Boundaries are only designed for intercepting errors that originate from 3 places in a React component: During render phase. In a lifecycle method. In the constructor.

How do you handle error boundaries in functional components?

In order to use Error Boundary in Functional Component, I use react-error-boundary. When we run this application, we will get a nice error display form the content of ErrorHandler component. React error boundary catches any error from the components below them in the tree.

Can we use error boundary in functional component?

As of v16. 2.0, there's no way to turn a functional component into an error boundary. The React docs are clear about that, although you're free to reuse them as many times as you wish: The componentDidCatch() method works like a JavaScript catch {} block, but for components.


2 Answers

The randomQuoteHandler replaces this.state.quotes array with a chosen quote which is an object. So on the second click, this.state.quotes.length is undefined.

You need to store the chosen quote in another state variable like randomQuote.

class App extends React.Component {
  state = {
    quotes: null,
    randomQuote: null,
  }
  componentDidMount() {
    fetch(
      'https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json',
    )
      .then(res => res.json())
      .then(data => {
        // console.log(data);
        this.setState({
          quotes: data.quotes,
        })
      })
    // console.log(this.state.quotes);
  }
  randomQuoteHandler = () => {
    const randNumb = Math.floor(Math.random() * this.state.quotes.length)
    const randomQuote = this.state.quotes[randNumb]
    this.setState({
      randomQuote: randomQuote,
    })
    console.log(this.state.quotes)
  }
  render() {
    return (
      <div>
        <button onClick={this.randomQuoteHandler}>gen</button>
        <p>{this.state.randomQuote !== null && this.state.randomQuote.quote}</p>
        <p>{this.state.randomQuote !== null && this.state.randomQuote.author}</p>
      </div>
    )
  }
}
like image 171
Ahmad Maleki Avatar answered Oct 20 '22 00:10

Ahmad Maleki


The problem is that in the randomQuoteHandler you are replacing the whole array of quotes with the random randomQuote object. The log at the end of this randomQuoteHandler function is showing that.

this.setState({
  quotes: randomQuote  // Array get replaced by one object
});

therefore the second time there is no array in the sate to read this.state.quotes.quote

like image 42
Amir-Mousavi Avatar answered Oct 20 '22 01:10

Amir-Mousavi