Stop rendering conditions like this
abdelrahman seada

abdelrahman seada @abdoseadaa

About: MERN Stack developer

Joined:
Jul 13, 2024

Stop rendering conditions like this

Publish Date: Jul 15 '24
909 67

we use conditions everywhere on our applications whether for state check or rendering some data into the view depending on some parameters. in this post will show some of how to render conditions in different way than using regular if(...) else {} blocks or even using ternary condition

for example (1)

type UserType = "admin" | "editor" | "user";

type User = { name: string; type: UserType };

const users: User[] = [
  { name: "john", type: "admin" },
  { name: "mike", type: "editor" },
  { name: "abdelrahman", type: "user" },
];

export default function Test() {
  const actions = ["create", "read", "update", "delete"];

  return (
    <div>
      {users.map((user) => (
        <div key={user.name}>
          {/* we need to render actions depending on user type */}
          <p>{user.name}</p>
          <div className="flex items-center">
            user actions:
            {user.type === "admin" && actions.map((a) => <Action a={a} key={a} />)}
            {user.type === "editor" && actions.filter((a) => a !== "create").map((a) => <Action a={a} key={a} />)}
            {user.type === "user" && actions.filter((a) => a === "read").map((a) => <Action a={a} key={a} />)}
          </div>
        </div>
      ))}
    </div>
  );
}

function Action(props: { a: string }) {
  const { a } = props;
  return <p className="px-2 py-1 border-[1px] mx-2 rounded-md">{a}</p>;
}


Enter fullscreen mode Exit fullscreen mode

output for example (1)

rendering using regular method

in this example we had to make a check condition for each user type to render his actions, as you can see this consumes a lot of code , harder to debug , harder to add more in future lastly looks ugly but this is a better way to do so

example (2)

type UserType = "admin" | "editor" | "user";

type User = { name: string; type: UserType };

const users: User[] = [
  { name: "john", type: "admin" },
  { name: "mike", type: "editor" },
  { name: "abdelrahman", type: "user" },
];

const userActionsStates: Record<UserType, string[]> = {
  admin: ["create", "read", "update", "delete"],
  editor: ["create", "read", "update"],
  user: ["read", "update"],
};

export default function Test() {
  return (
    <div>
      {users.map((user) => (
        <div key={user.name}>
          {/* we need to render actions depending on user type */}
          <p>{user.name}</p>
          <div className="flex items-center">
            user actions:
            {userActionsStates[user.type].map((a) => (
              <Action key={a} a={a} />
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

function Action(props: { a: string }) {
  const { a } = props;
  return <p className="px-2 py-1 border-[1px] mx-2 rounded-md">{a}</p>;
}


Enter fullscreen mode Exit fullscreen mode

output for example (2)

  • output is the same as example (1)

key changes

grouping each user type in object key and value should be what ever you want to render
in this case we pass each user type actions like the following

grouping in objects

and here instead of rendering each condition like example (1) or making a ternary condition we get user actions from grouped object userActionsStates and just render whatever in the key's value and Voilà it's only one line of code

conditions using object

what about else ? what if we pass a user type that does not exists in the object ?

in this case we can add a default key in the object , this key will be used in false or undefined cases
like the following :


const userActionsStates : Record<UserType , string[] > = {
    admin: ["create", "read", "update", "delete"],
    editor: ["create", "read", "update"],
    user: ["read", "update"],
    default : ["read"]
}


Enter fullscreen mode Exit fullscreen mode

if we updated users with new user that it's type is not defined like the last user object

updated users with new undefined user type

then we will make a small change to the render method

<div className="flex items-center">
  user actions:
  {(userActionsStates[user.type] ?? userActionsStates["default"]).map((a) => (
    <Action key={a} a={a} />
  ))}
</div>

Enter fullscreen mode Exit fullscreen mode

using null coalescing ?? we ensure that it will render as expected on
all conditions. :)

updated users output

please note

using this method you can render anything in the key's value string , number , array , Component , ...etc.

summary

  • easy to read , debug and update 🧑‍💻
  • looks cool 😌
  • less code

it's up to your creativity and imaginations 💡🔥

Comments 67 total

  • alyouma akmal
    alyouma akmalJul 16, 2024

    Nice code

  • Mateus Guedes
    Mateus GuedesJul 16, 2024

    Nice one!!!

  • Tinashe Gunda
    Tinashe GundaJul 16, 2024

    Well executed!

  • Isaac Klutse
    Isaac KlutseJul 16, 2024

    very understandable.

  • Nwosa Tochukwu
    Nwosa Tochukwu Jul 16, 2024

    Nice. Thank you for this

  • Bernardo Guerreiro
    Bernardo GuerreiroJul 16, 2024

    great

  • Ronak Khunt
    Ronak KhuntJul 16, 2024

    Well explained!

  • SUYASH AGNIHOTRI
    SUYASH AGNIHOTRIJul 16, 2024

    Nice explanation.

  • abdelrahman seada
    abdelrahman seadaJul 16, 2024

    didn't expect that anyone would see this post
    cat meme

  • ngocleDevMobile
    ngocleDevMobileJul 17, 2024

    Greate!!!!!

  • Olu
    OluJul 17, 2024

    I like this.

  • Shrijal Acharya
    Shrijal AcharyaJul 17, 2024

    Just one simple piece of advice: Instead of using 4 spaces for indentation in code snippets for blogs, I think it's better to use 2 spaces as it reduces the need for horizontal scrolling.

    Great read. 👌

    • abdelrahman seada
      abdelrahman seadaJul 17, 2024

      thanks for this advice 🤍

    • John
      JohnNov 14, 2024

      How about using the tab character? That what it is meant for and every one can set the space to what ever fits best for one.

  • Mohammed BENGUEZZOU
    Mohammed BENGUEZZOUJul 17, 2024

    Brilliant <3

  • Harshad
    HarshadJul 17, 2024

    Nice

  • KEY UNG KIM
    KEY UNG KIMJul 17, 2024

    thanks 👌

  • bop
    bopJul 19, 2024

    github.com/gvergnaud/ts-pattern

    this is also a good alternative

  • Ehsan Safari
    Ehsan SafariJul 19, 2024

    You are doing great

  • abdulrhman-moh
    abdulrhman-mohAug 26, 2024

    this is awesome

  • Mohammed CHRIATT
    Mohammed CHRIATTAug 31, 2024

    Thank you 🙏

  • threestarss
    threestarssAug 31, 2024

    There is nothing wrong with conditions, you just reshaped the data you are working with

    • abdelrahman seada
      abdelrahman seadaSep 2, 2024

      exactly, there is nothing wrong with conditions anyways , it's just a better approach

  • KookaKoora
    KookaKooraAug 31, 2024

    Amazing tip!

  • Gabriele Zizzari
    Gabriele ZizzariSep 7, 2024

    Perfect explanation!!!
    simple way to do clean code :)

  • Hamdi Kamel
    Hamdi KamelSep 25, 2024

    This is great!

    You get to simplify things further by creating objects with properties that point to specific values instead of checking nonstop for multiple values.

  • Shahadat Hossain
    Shahadat HossainOct 8, 2024

    I think this is not a matter of condition. It's a matter of good practice. Example 1 is easy to understand for beginners, but the other one is good to maintain and easy to extend.

    • abdelrahman seada
      abdelrahman seadaOct 10, 2024

      it's a better way to write conditions as you said easy to maintain , extend and debug

  • O.Tito.R.
    O.Tito.R.Oct 11, 2024

    Thank you for posting, I am aspiring to be able to write and understand fluently! Reading these articles from inside perspectives helps tremendously!

  • Sidhant Pandey
    Sidhant PandeyOct 13, 2024

    Really Great Approach, Surely i am going to use in my Project, Awsome Thanks!

  • Leon Gattermayer
    Leon GattermayerNov 12, 2024

    One more small advice. Just use ENUM for those roles across the project.

  • VavaXX2
    VavaXX2Nov 12, 2024

    imperative vs declarative

  • KristofaJosh
    KristofaJoshNov 14, 2024

    Nice read!! a little improvement for the action array.

    const actions = {
      create: 'create',
      read: 'read',
      update: 'update',
      delete: 'delete',
    } as const;
    
    Enter fullscreen mode Exit fullscreen mode

    create a type of actions

    type Actions = (typeof actions)[keyof typeof actions];
    
    Enter fullscreen mode Exit fullscreen mode

    then

    const userActionsStates : Record<UserType , Actions[] > = {
        admin: ["create", "read", "update", "delete"], // action.create | action.delete
        editor: ["create", "read", "update"],
        user: ["read", "update"],
        default : ["read"]
    }
    
    Enter fullscreen mode Exit fullscreen mode

    Voila!
    no one should add something weird within 😏
    ...

  • Hugo Pineda
    Hugo PinedaDec 10, 2024

    no thank you. Over-abstractions are harder to maintain when the app grows.

    • abdelrahman seada
      abdelrahman seadaDec 11, 2024

      Over-abstractions ?
      so when your app grows abstractions is harder to maintain.
      Ok

  • Berkan Serbes
    Berkan SerbesDec 27, 2024

    Inspiring 👍

  • Aayush Goyal
    Aayush GoyalJan 6, 2025

    Little things like these make you a pro developer. All the best to everyone and thanks to the author for sharing a good and short article.

  • Brian Cao
    Brian CaoJan 12, 2025

    My approaching as following

    /**
     * You declare the data in type of array
     * Then, you can loop through the list when you neeed
     */
    
    const ACTIONS = ['create', 'read', 'update', 'delete'] as const
    const USER_TYPES = ['admin', 'editor', 'user', 'anonymous'] as const
    
    /**
     * Types guard
     */
    type Action = typeof ACTIONS[number]
    type UserType = typeof USER_TYPES[number]
    
    /**
     * Your userActions data with types guard
     */
    const userActions : Record<UserType , Action[] > = {
        admin: ["create", "read", "update", "delete"],
        editor: ["create", "read", "update"],
        user: ["read", "update"],
        anonymous: ["read"]
    }
    
    Enter fullscreen mode Exit fullscreen mode
  • Tahdi Islam
    Tahdi IslamFeb 6, 2025

    Valuable, Thanks for sharing

Add comment