Ternarys are great for simple conditional rendering, generally involving just a single state variable (i.e.
isLoading). Things get more complicated when rendering depends on multiple variables, such as in the example above. Here, we want to render a loading component
MyLoadingIndicator while the data is being fetched, then render either an error component (
MyRenderErrorComponent) if the response contains an error, or render the data (
The (generally) bad approach
We could simply nest ternary statements, as in lines #25-29. Even for just two render variables (
hasError) this is challenging to read and understand.
The better approach
Instead of nesting ternary statements, we could treat each component's render state independently (lines #53-55) and rely on short-circuit evaluation to render the correct component. For each component, we specify the necessary conditions under which it should render. Since
MyRenderErrorComponent should only render when
isLoading = false and
hasError = true, we can simply specify that here.
There is (at least) one important caveat to keep in mind: more "specific" render logic should come before less specific logic. For example, we could have an separate error component we want to render if the error result is fatal, and keep
MyRenderErrorComponent for all other errors. We change the
return as follows:
if (!isLoading && hasError && isFatal) return <MyRenderFatalErrorComponent />
if (!isLoading && hasError) return <MyRenderErrorComponent />
The order here is important, since
!isLoading && hasError will always evaluate to
!isLoading && hasError && isFatal evaluates to
true, but not vice-versa. Reversing the order will result in
<MyRenderErrorComponent /> always rendering instead of
Barry Michael Doyle has a great blog post discussing various conditional rendering approaches.