It's interesting that this is a case where React does need to somewhat reinvent the wheel. The best aspect of JSX is that you can use native JS constructs. So instead of a custom HTML attribute (e.g. ng-if in Angular, v-if in Vue), you can just use a JS if statement.
It makes me wonder what a UI language/system would look like if it were designed from the ground up to be declarative. Would it end up just looking a lot like React?
Anyway, this looks useful. Error handling is one of the harder aspects of programming in my experience, so I'm glad this exists now.
> It makes me wonder what a UI language/system would look like if it were designed from the ground up to be declarative. Would it end up just looking a lot like React?
You could find one answer to that question in Elm[1], and indeed it does look a lot like React. Although it generally handles exceptions by never letting them happen in the first place :)
>It's interesting that this is a case where React does need to somewhat reinvent the wheel.
Yep. React has to reinvent the wheel everywhere at the component boundaries. For example, one could see <Foo /> (which is really {type: Foo}) as a “reinvented” Foo() function call. Or see this.state as “reinvented” local variables, and this.props as arguments.
I think it’s expected that, as React gets more expressive (there are other features in the pipeline), it will unfortunately have to provide its own way to express these because it goes more into the language territory. But of course we’ll try our best to make these things look familiar in JS.
> It makes me wonder what a UI language/system would look like if it were designed from the ground up to be declarative.
QML [0] was an attempt to do that. I would say it was a very successful attempt in terms of quality of the final product. It's probably the only UI toolkit that I enjoyed using so far.
> It makes me wonder what a UI language/system
> would look like if it were designed from the
> ground up to be declarative
XSLT?
I think most people have seen XSLT only in trying to do simple transformations, without getting properly under its skin. Personally I've written a bunch of stuff in it -- a testing suite, graph traversal algorithms -- that make you appreciate it's absolutely a functional declarative language.
This is awesome! I'm relatively new to React - just a few months in - but have already hit these cryptic errors and struggled to diagnose. This will help not just general stability of apps, but probably troubleshooting these errors as well (via ability to reduce the impact area of crashes).
If you don't add an error boundary, and you get an exception, then the app will unmount. The error will get logged to console in development even if the app swallows the error. So yes, it will help notice (and fix) such issues sooner. But I still recommend the explicit then(onSuccess, onError) form so that unhandled exceptions go through the top of the stack and register as uncaught errors in DevTools.
* If error boundary could catch its own errors, what happened if it tried to render error message and threw then? It would get into an infinite loop, trying to handle its own error and failing again. Thanks to the restriction, this can never happen.
When a component throws, it means the user's code has encountered an unexpected error. That means the component is in an unexpected state, and you cannot reasonably say that that component can rebuild it's (internal) state to a stable (and renderable) state.
but in theory at that point in the operation, we're still in the process of building a new DOM (hence the old DOM is still around)? So you could replace the component with an error node and during the diffing process replace with the old node?
Not great but if you hit a fatal error you hit a fatal error
personally I would rather a website tell me that an error occurred using the new mechanism than fall back to a previous version of the DOM and have me wondering why clicking that button isn't doing anything.
If you package this up as a higher-order component, you basically get this behavior. It would be pretty easy to do. But I think the way they designed it is smart. You want components that account for very granular concerns, and then compose them together to get more complex behavior.
Thanks! We wrap handlers for Asana since we're unsure if our data store is in a sane state after an error. The logic is much the same as the error boundary
I was skeptical at first, but after reading through how it works and why it was done, I love it. In fact, it would have made quite a few bugs much easier to track down.
This is not very useful because it only allows for error handling based on JS exceptions, which is rarely used (and in fact shouldn't be) for user defined error states. It also won't work with Promises, generators, async functions, etc. unless you setState({hasError: true}) on your error boundary differently than with componentDidCatch(). I'm not sure how this is useful in dev time, or how this is useful in productions. Throw when input invalid?
This feature is for gracefully recovering from JavaScript errors that occur in production as a result of programmer mistakes.
For example, Facebook heavily uses error boundaries in ads code. Even if one widget fails rendering, it doesn’t take down the entire page. You’re going to have some runtime errors if you use JavaScript, but this feature ensures you can gracefully recover from them (instead of just breaking the whole app as React 15 and earlier did).
There are two other effects of this change:
* React no longer has its own cryptic errors (because it doesn’t get “confused” when user code throws, and can cleanly fail fast if there is no error boundary).
* Errors reported to the boundaries have a component stack trace attached to that, so you can know where exactly in the hierarchy the failure occurred. This can be pretty useful when debugging.
I suppose that it's not meant to deal with errors normal to the use of the application (like not entering an email in an input) but rather to exceptions and JavaScript errors. I'm imagining stuff like receiving data of an unexpected format from the server, which might break your application in unexpected ways (i.e. put it in an undefined state that is hard to reason about and would make it better to just "show a generic error").
It makes me wonder what a UI language/system would look like if it were designed from the ground up to be declarative. Would it end up just looking a lot like React?
Anyway, this looks useful. Error handling is one of the harder aspects of programming in my experience, so I'm glad this exists now.