DEV Community

loading...

Nested Ternary statements in React JSX

samba_code profile image Sam Atkinson ・1 min read

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:

Discussion (5)

pic
Editor guide
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
georgecoldham profile image
George

I just use indentation.

const drink = dislikeCoke
    ? 'fanta'
    : likesCherry
        ? 'cherryCoke'
        : 'dietCoke';
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.