In the last exercise, we practiced rendering a fallback using the FallbackComponent
prop assigned to an <ErrorFallback>
component. The <ErrorFallback>
component received two props itself: error
and resetErrorBoundary
:
function ErrorFallback({ error, resetErrorBoundary }) { // Handle the error / resetErrorBoundary logic... } // Later in some rendered JSX... <ErrorBoundary FallbackComponent={ErrorFallback}> <ProtectedComponent /> </ErrorBoundary>
The two values, error
and resetErrorBoundary
, are automatically passed as props to whatever component is provided as the FallbackComponent
. But if we needed to pass in additional props to <ErrorFallback>
, how might we do that?
Passing additional props to our fallback UI allows us much greater flexibility in how we render that fallback. We may want to provide more details about the thrown error or switch between different UIs depending on the error. For any of these scenarios, the solution can be achieved using the basics of React!
Rather than providing ErrorFallback
as the value of the FallbackComponent
prop, we can provide an inline anonymous function component like so:
function ErrorFallback({ error, resetErrorBoundary, newProp }) { // Handle the error / resetErrorBoundary logic... // But now we also have the newProp value! } // Later in some rendered JSX... <ErrorBoundary FallbackComponent={(props) => ( <ErrorFallback {...props} newProp={"foo"} /> )} >
Let’s break it down:
- The
<ErrorBoundary>
component is still rendered with theFallbackComponent
prop - The component passed as the
FallbackComponent
is an inline anonymous function component with aprops
argument. We know that thisprops
argument is an object with two values:error
andresetErrorBoundary
. - The inline anonymous function component returns the
<ErrorFallback>
component with the originalprops
values (error
andresetErrorBoundary
) along with anewProp
value (in this case"foo"
).
Passing in a value like "foo"
is quite silly but it illustrates the point: we can pass any additional props to our fallback UI using this approach! Let’s see how this may be more useful in our example application.
Instructions
Take a look at the App
component at the bottom of index.js
. Notice that we’ve changed some things around.
- Instead of manually rendering each
<LightSwitch>
, we are using an array ([1,2,3,4]
) and the.map()
array method to automatically render each<LightSwitch>
- All four
<LightSwitch>
components are individually wrapped with their own<ErrorBoundary>
- The
switchNumber
prop for each<LightSwitch>
is assigned the corresponding array value (num
).
First, press the Run button and play around with the application to make sure it behaves as expected.
Currently, if you break each component, the fallback UI is the same. Instead, let’s have each fallback UI display the message An error was found in switch X
and make the button display Reset switch X
, where X
is the broken switch number.
First, let’s modify the ErrorFallback
function component. Add in a switchNumber
prop and modify the returned JSX such that the <h2>
element and the <button>
element displays the switchNumber
.
Even if you complete this step properly, you will notice that the switchNumber
value isn’t being displayed. That makes sense — we haven’t passed it to ErrorFallback
yet! Move on to the next step.
Now that our ErrorFallback
can accept a switchNumber
prop, let’s pass it one!
Inside the App
function component, modify the returned JSX such that the <ErrorBoundary>
component has a FallbackComponent
prop whose value is an inline anonymous function component. This function component should:
- Be an anonymous arrow function that accepts
props
as an argument - Return an
<ErrorFallback>
component with theprops
spread using the...
operator and aswitchNumber
prop with a value ofnum
.
After completing this step, try pressing all four “Bad Switch” buttons. You should notice that each piece of fallback UI shows a unique message!