<!doctype html>

<html>
  <head>
    <script src="https://unpkg.com/react@16.0.0/umd/react.production.min.js"></script>
    <script src="https://unpkg.com/react-dom@16.0.0/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
    
    
  </head>

  <body>
    <div id="root"></div>
    <script type="text/jsx" src="script.jsx"></script>
  </body>
</html>

let sendToErrorReporting = (error, info) => {
  console.log('Error:',error)
  console.log(info)
}

class MyErrorBoundary extends React.Component {
constructor(props) {
  super(props);
  this.state = {
    hasError: false
  };
}

componentDidCatch(error, info) {
  sendToErrorReporting(error, info);

  this.setState(state => ({ ...state, hasError: true }));

}

render() {
  if (this.state.hasError) {
    return <div>Sorry, something went wrong.</div>;
  } else {
    return this.props.children;
  }
}
}

class Profile extends React.Component {
onClick = () => {
  this.setState(state => {
    throw new Error("BANG!!!");
    return { ...state };
  });
};

render() {
  
  const { user }  = this.props;
  
  let name = (user)?user.name : 'N/A' ;
  
  return (
    <div onClick={this.onClick}>
      Name: {this.props.user.name}
    </div>
  );
}
}

class App extends React.Component {
constructor(props) {
  super(props);
  this.state = {
    user: { name: "Andrew - (you can click me as well)" }
  };
}

updateUser = () => {
  //NOTE: If we throw an exception before the setState function returns then
  // the catch handler in the error boundary will not be triggered
  //as the this function is in a component that is the parent of the error boundary
  this.setState(state => {
        //throw new Error("BANG!!!"); //This will cause the new behaviour of rendering nothing
    return { ...state, user: null }
    
  });
};

render() {
  return (
    <div>
      <MyErrorBoundary>
        <Profile user={this.state.user} />
        <button onClick={this.updateUser}>Do Something</button>
      </MyErrorBoundary>
    </div>
  );
}
}

ReactDOM.render(<App />, document.getElementById("root"));