React v16 beta is out, suddenly everyone needs to catch UI errors.

Update 29/7/2017: Thanks to Dan Abramov for explain me in more detail some scenarios.

A few days ago (26/7/2017) the React team released their new beta version introducing several new features which received some attention among the community. I’ve being playing around with it and I would love to share my findings so far.

The feature that got most of attention of the community was a new hook known as componentDidCatch which supports a more declarative way to handle error as explained in this post.

Error Handling, how to catch all the things?

Even when the try/catch feature has been around for a long time, it seems like everyone is in the mood for catching error in the last couple of days, however, I’ve found that some people seem to be confused about the way it works, so others (like me) just don’t like to read the instructions 🤣.

I’ve found 5 interesting cases that can potentially introduce some confusion around.

i ❤ codesanbox

I’ve set a few errors around to try to understand how this works, what kind of errors can pass and what others can’t. The first rule to understand is that a component has a componentDidCatch will serve as a some sort of DMZ, which means it won’t be able to catch errors on itself but other nodes down the tree. You can test this going to the UseCase.js and uncomment the line 22, it will throw a runtime error and the whole application will crash.

First case, the null error (render method).

The most predictable case would be forcing a null value down the tree forcing a runtime error as show on the Set name to null example. When the component re-renders after a state change, it will find and catch a runtime error, so far so good, my application did not crash.

Second case, throw an error on a event handler.

This case is interesting, error handlers do not work when call directly on an even handler. Event handlers could catch the errors but they are less important since they do not corrupt the UI state.

Basically, the rule of thumb is that errors from render/constructor/lifecycle are caught.

Third case, force a runtime error

If we force a runtime error calling an undefined function after an event handler, the component does not catch the error, similar case like the second case.

why render/constructor/lifecycle? Because, they happen before the UI have rendered, so render result is not consistent.

Fourth Case

Now the interesting case, we can try to force a setState and throwing an error during the process, this will help us to understand the async nature of this operation and how to start using it better, check next case.

Fifth Case

If you needed a reason to start passing a function to the a setState operation, now it’s the time, notice how this subtle error is caught by the boundary due to the through the order of how the function is executed.

The reason why this case is caught is because updater functions are called during rendering 💡

So what’s next…?

Even when I think this will make our life easier I would suggest to use it and not abuse it, after all, let’s be honest… na nvm. 🤣 just find a good place to put your 💩.

What else?

The other feature that didn’t got too much attention but I loved was being able to render multiple Components without a single root as long as you return an array.

Feel free to check the Test component on my sample, remember to add your keys 👊.

Have you found a another caveat about this release? please let me know! I’m happy to talk about it 👋🏼.

Thanks to Karen Serfaty and Dan Abramov for the revision.