React Typescript conditional rendering using objects

ahmeddammarr

Ahmedammarr

Posted on October 19, 2021

React Typescript conditional rendering using objects

Lately, I've been looking for a better way to write clean conditional rendering code instead of ternary and && operators and even if statements, because sometimes they can be confusing and I found that I can write the same functionality with objects, it makes the code more readable. let's see how we can write a well-typed object to render a component based on the parent component state and props

export default function Products({state}:ProductsStateEnum)
:ReactElement {
const [_ProductsState, setProductsState] = useState(state)
  const ProductsState: { [key in ProductsStateEnum]: ReactElement } = {
    loading: <Loader width={150} />,
    failed: (
      <div>
          <Badge bg='danger'>Somethig Went Wrong</Badge>
      </div>
    ),
    done: (
      <>
        {products?.map(
          ({ id, title, image, description, category, price }) => (
            <ProductCard
              key={id}
              id={id}
              title={title}
              description={description}
              category={category}
              price={price}
              image={image}
            />
          )
        )}
      </>
    )
  }

  return <div className='row p-3'>{ProductsState[_ProductsState]}</div>
}
Enter fullscreen mode Exit fullscreen mode

We notice here that we didn't write any if statement or any operator, based on the state the component will render the React component with key that's equal to the _ProductsState,

Another and better solution from lukeshiru is using functions/components

import type { FC } from "react";

type State = "loading" | "failed" | "done";
type ProductsProps = { readonly state?: State };

export const Products: FC<ProductsProps> = ({ state = "loading" }) => {
    const ProductsState = (
        {
            loading: () => {/* Your loading code here */},
            failed: () => {/* Your failed code here */},
            done: () => {/* Your done code here */}
        } as Record<State, FC>
    )[state];

    return (
        <div className="row p-3">
            <ProductsState />
        </div>
    );
};
Enter fullscreen mode Exit fullscreen mode

in the above code we can render only the exact state components when needed.

tell me if you know another way to write readable conditional rendering options!

💖 💪 🙅 🚩
ahmeddammarr
Ahmedammarr

Posted on October 19, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related