Cleaner way to write conditionals in JSX

Code Clean in React

Hello, I'm Hardik and this is my first blog ever πŸ’β€β™‚οΈ. I am an SDE internπŸ±β€πŸ’» working a lot on React. I love Neat and Clean code I always strive for it, one of the things I'm weak at is naming variables LOL.πŸ˜₯

Problem

Conditionals in JSX make codes messy and less readable. See issue in this Stackoverflow issue. If the codebase is large enough and there is a lot of conditions and logic for JSX things will get out of hand pretty sooner.

I don't want my code to look like this or similar alternatives, NEVER.

{ this.state.loadingPage
  ? <span className="sr-only">Loading... Registered Devices</span>
  : [
      (this.state.someBoolean
        ? <div key='0'>some title</div>
        : null
      ),
      <div key='1'>body</div>
    ]
}

Solution

Inspired by jsx-control-statements . I will show you some good patterns in JSX which can help make JSX cleaner and readable.

Let's start with easy.

function Component(props) {
  return <>{props.isOpen ? <h1>Goku is the best</h1> : null}</>;
}

We can make an If Component to handle Such conditions

export function If(props) {
  if (!!props.condition) {
    return props.children;
  }
  return null;
}
// use it like this 
function App(){
  return <If condition={true}>Goku is the best</If>
}

Liked it? Lemme show you a more interesting pattern. This is Called Choose Element. you can use it from here Let me show you how you can implement it. (not a perfect implementation, just enough to explain you a concept, you can use it from the library)

What I want ?

 <Choose>
        <When condition={true}>I want Tea</When>
        <When condition={false}>Job in FAANG</When>
        <When condition={true}>I love neffex</When>
        <OtherWise>Tea/Coffee + Sandwich</OtherWise>
 </Choose>


// above code should be transformed to
  {true ? (
        <>IwantTea</>
      ) : false ? (
        <>Job in FAANG</>
      ) : true ? (
        <>I love neffex</>
      ) : (
        <>Tea/Coffee + Sandwich</>
      )
   }

output : I want Tea

Usecase of Otherwise

<Choose>
        <When condition={false}>I want Tea</When>
        <When condition={false}>Job in FAANG</When>
        <When condition={false}>I love neffex</When>
        <OtherWise>Tea/Coffee + Sandwich</OtherWise>
</Choose>

output: Tea/Coffee + Sandwich

Let's start with easy and build When and Otherwise component

export const OtherWise: React.FC<{}> = (props) => {
  return props.children;
};

export const When: React.FC<IWhenProps> = (props) => {
  return <>{props.children}</>;
};
interface IWhenProps {
  condition: boolean;
}

pretty easy! The real game is Choose now. Let's go ahead and implement this Choose component. Choose component will look for the first When component with the condition prop as true and return that from Choose component. if no When component has a true condition. we will look for Otherwise component and return it.


// NOT COMPLETE IMPLEMENTATION
const Choose: React.FC<{}> = (props) => {
  let toReturn: React.ReactNode = null;
  // check if multiple childs
  if (Array.isArray(props.children)) {
    const { children } = props;
    for (let index = 0; index < children.length; index++) {
      const el = children[index];
      if (el.type.name === "When" && el.props.condition) {
        return el;
      }
    }
  } else {
    if (props.children.props.condition) {
      return props.children;
    }
  }

  // check if any otherwise component present
  // to use otherwise you must have multiple
  // components
  for (let index = 0; index < props.children.length; index++) {
    const el = props.children[index];
    if (el.type.name === "OtherWise") {
      return el;
    }
  }

  return toReturn;
};

I hope you liked it. Patterns are opinionated. You may like this or not depends on you. You can follow me on Twitter mobile.twitter.com/sindhiboi. I sometimes write.

Β