My Two Favorite React Tricks

Published See discussion on Twitter

There are generally two rarely used patterns in React that I really enjoy getting to use in applications that I work on.

These both are:

  • Using key
  • Throwing within a state setter

On Key

In React, key is one of those early concepts that you learn that seems to only be documented for use within lists. However it is an incredibly useful feature that most developers don't use when building applications!

If you ever find yourself realizing that you need to reset the state, or refs, of a particular component based on some value in the parent a key that can be changed on the component is a really useful way to do so!

I've generally recommended this for updating components that may perform some computation when the component mounts, but doesn't re-compute that operation at a later point in time.

1<Child key={someCondition ? 'a' : 'b'} />
1<Child key={someCondition ? 'a' : 'b'} />

Throwing Within A State Setter

I've written about this concept briefly in my post on React Error Boundaries, however I figured I'd write about the concept in another post since I really enjoy this feature.

If you ever find yourself wanting to trigger an error boundary from an event handler, or even an asynchronous function call (e.g. within a promise callback, or another microtask), you can call a setState function with a function that throws in the body!

1function handleClick() {
2 try {
3 // do some logic
4 } catch (error) {
5- // How do I trigger an error boundary here?
6+ setState(() => {
7+ throw error;
8+ });
9 }
10}
1function handleClick() {
2 try {
3 // do some logic
4 } catch (error) {
5- // How do I trigger an error boundary here?
6+ setState(() => {
7+ throw error;
8+ });
9 }
10}

I use this pattern so often that I usually add a useErrorBoundary hook in most of my side projects:

1import { useState } from 'react'
2
3export default function useErrorBoundary() {
4 let [, set] = useState()
5 return (error) =>
6 set(() => {
7 throw error
8 })
9}
10// in another file...
11function Component() {
12 let trigger = useErrorBoundary()
13
14 function handleClick() {
15 trigger(new Error('Yo!'))
16 }
17 //...
18}
1import { useState } from 'react'
2
3export default function useErrorBoundary() {
4 let [, set] = useState()
5 return (error) =>
6 set(() => {
7 throw error
8 })
9}
10// in another file...
11function Component() {
12 let trigger = useErrorBoundary()
13
14 function handleClick() {
15 trigger(new Error('Yo!'))
16 }
17 //...
18}