1

I've got the following working JavaScript class.I'm hoping there is an ES6 way of doing it without having to use the constructor keyword and also minimize the use of this. I've tried statements like

state = {hasError: false}

and that works for just hasError, but can't figure out how to handle the function bind. I'm hoping not to have to do that like I don't have to use this to access state with the new syntax.

export default class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
    this.updateHasErrorsToFalse = this.updateHasErrorsToFalse.bind(this);
  }

  updateHasErrorsToFalse() {
    this.setState((prevState) => ({
      hasError: false,
    }));
  }

  //state = { hasError: false, error: null,  };

  static getDerivedStateFromError(error) {
    return {
      hasError: true,
      error: error.message
    };
  }

  componentDidCatch(error, errorInfo) {
    // You can also log the error to an error reporting service
    console.log(error, errorInfo);
  }

  updateHasErrorsToFalse() {
    this.setState((prevState) => ({
      hasError: false,
    }));
  }

  render() {
    function addExtraProps(Component, extraProps) {
      return <Component.type {...Component.props} {...extraProps} />;
    }

    if (this.state.hasError) {
      return addExtraProps(this.props.fallback, {
        error: this.state.error,
        resetError: this.updateHasErrorsToFalse,
      });
    }
    return this.props.children;
  }
}
Peter Kellner
  • 14,748
  • 25
  • 102
  • 188
  • This question has been answered here https://stackoverflow.com/questions/32192682/react-js-es6-avoid-binding-this-to-every-method – Eduard Jan 16 '22 at 17:07
  • 1
    NB: `constructor` is not a keyword. – trincot Jan 16 '22 at 17:09
  • @trincot what is "constructor"? – Peter Kellner Jan 16 '22 at 17:11
  • Whatever you want it to be, but if you use it as a method name in a `class` syntax, it will serve as the constructor. – trincot Jan 16 '22 at 17:13
  • "*I'm hoping there is an ES6 way of doing it without having to use the `constructor` keyword and also minimize the use of `this`*" - not sure what you think is wrong with using constructors and the `this` keyword? – Bergi Jan 16 '22 at 17:14
  • is constructor a reserved word? I'm confused – Peter Kellner Jan 16 '22 at 17:14
  • "*I can't figure out how to handle the function bind*" - well in exactly the same way as you handled `state`, just convert it into a class field: `updateHasErrorsToFalse = this.updateHasErrorsToFalse.bind(this);`. – Bergi Jan 16 '22 at 17:15
  • No, [`constructor` is not a reserved word](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#keywords) – trincot Jan 16 '22 at 17:16
  • @berg, I find statements like `this.updateHasErrorsToFalse = this.updateHasErrorsToFalse.bind(this);` confusing to write and read – Peter Kellner Jan 16 '22 at 17:16

1 Answers1

2

By doing the following, you bind this to function manually.

this.updateHasErrorsToFalse = this.updateHasErrorsToFalse.bind(this);

Instead of that, you can use the arrow function notation which has the lexical binding of this.

  updateHasErrorsToFalse = () => {
    this.setState((prevState) => ({
      hasError: false,
    }));
  }

And you can remove constructor and have state instance as below.

Instead of

 constructor(props) {
    super(props);
    this.state = { hasError: false };
    this.updateHasErrorsToFalse = this.updateHasErrorsToFalse.bind(this);
  }

Just keep following in the class level

state = { hasError: false };
Amila Senadheera
  • 12,229
  • 15
  • 27
  • 43