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>
}
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>
);
};
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!
Top comments (1)
Thank you, your solution is better i'll update the article and use your example and mention your name is that okay with you ?