DEV Community

Sam Atkinson
Sam Atkinson

Posted on

9 3

Nested Ternary statements in React JSX

After discovering our ESLinter hasn't been running for some time I've spent most of today going through trying to fix a whole bunch of eslint and a11y issues in our React app. I hit quite an interesting one:

/*eslint no-nested-ternary: "error"*/

Which basically means, don't do this:

const drink = dislikeCoke ? 'fanta' : likesCherry ? 'cherryCoke' : 'dietCoke';

Which I think in general everyone can get behind as a rule. It's not readable code, even when split over multiple lines with indentations, and should be broken out into if statements.

However, this is a very common pattern in React where we can use ternary statements to do conditional rendering in a component.

 <h1>Data Loader!</h1>
        { this.state.loading ? 
        <h2>It is Loading.</h2>
          : this.state.data ? 
          <h2>{this.state.data}</h2>
          :<h2>There was no result!</h2> 
        }

(This is a very contrived example).

I poked around on the internet for a while and the best alternative I've found to this is to extract the second part of the ternary into a stateless functional component. The component can still live in the same file so it's still quick and easy to comprehend, and I found it to be a nice way to encapsulate the UI code.

const DataDisplay = ({data}) => data ? 
          <h2>{data}</h2>
          :<h2>There was no result!</h2> 

          ...

          { this.state.loading ? 
        <h2>It is Loading.</h2>
          : <DataDisplay data={this.state.data}/>
        }

Full example codepen below:

Sentry image

Make it make sense

Make sense of fixing your code with straight-forward application monitoring.

Start debugging β†’

Top comments (6)

Collapse
 
evadonnathan profile image
Nathan Dixon β€’

Another option is to do an inline JSX functional component:

<h1>Data Loader!</h1>
        { () => {
            if (this.state.loading) { 
                return (<h2>It is Loading.</h2>)
            } else {
                if (this.state.data) { 
                    return (<h2>{this.state.data}</h2>)
                } else {
                    return <h2>There was no result!</h2> 
                }
            }
        }
Enter fullscreen mode Exit fullscreen mode
Collapse
 
josebrownex profile image
Jose Browne β€’ β€’ Edited

For others running into this issue the above won't work unless it's immedietly invoked

{(() => {
  ...
})()}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
georgecoldham profile image
George β€’

I just use indentation.

const drink = dislikeCoke
    ? 'fanta'
    : likesCherry
        ? 'cherryCoke'
        : 'dietCoke';
Enter fullscreen mode Exit fullscreen mode
Collapse
 
aquasar profile image
Alex Quasar β€’

I think your solutions is more complicated. I prefer the "Don't do this example"
Personally for me, Ternary in ternary is probably okay but if you are going to nest deeper than you probably should be rewriting your code in a nicer way, switch and case statements?

Collapse
 
peppermint_juli profile image
Juliana Jaime πŸŽƒ β€’

It was very helpful, thank you!!

Collapse
 
gabrielmlinassi profile image
Gabriel Linassi β€’

Cool! Much easier to get it on first glance. I just think when the code is not split into a different file, there's no need to pass the data as parameters since it has straight access to it.

Neon image

Next.js applications: Set up a Neon project in seconds

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Get started β†’

πŸ‘‹ Kindness is contagious

If this article connected with you, consider tapping ❀️ or leaving a brief comment to share your thoughts!

Okay