Understanding the "Element" React Component: A Flexible Approach to Conditional Rendering

Serif COLAKEL - Jan 14 - - Dev Community

When working with React, developers often encounter scenarios where they need to conditionally render elements based on certain conditions. The provided Element component aims to simplify this process by introducing a flexible and intuitive approach to conditional rendering.

The Problem

When working with React, developers often encounter scenarios where they need to conditionally render elements based on certain conditions. For example, a developer may want to render a button only if a user is logged in. Or, a developer may want to render a form only if a user is logged out.

In these scenarios, developers often use conditional rendering strategies such as the && operator or the ternary operator. While these strategies are effective, they can be difficult to read and maintain. For example, the following code snippet uses the && operator to conditionally render a button:

import React from 'react';

export default function Usage() {
  const isLoggedIn = true;

  return (
    <div>
      {/* ✅ Button will be rendered if isLoggedIn is true */}
      {isLoggedIn && <button>Logout</button>}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

While this approach is effective, it can be difficult to read and maintain. For example, the following code snippet uses the ternary operator to conditionally render a form:

import React from 'react';

export default function Usage() {
  const isLoggedIn = true;

  return (
    <div>
      {/* ✅ Form will be rendered if isLoggedIn is true */}
      {isLoggedIn ? (
        <form>
          <input type="text" />
          <input type="password" />
          <button>Login</button>
        </form>
      ) : null}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

The Element component aims to simplify this process by introducing a flexible and intuitive approach to conditional rendering. It leverages TypeScript to provide a type-safe interface and improve code clarity.

Overview - Element Component

The Element component is a React component that allows developers to conditionally render elements based on specific conditions. It leverages TypeScript to provide a type-safe interface and improve code clarity.

import React, { ComponentProps } from 'react';

type ElementBaseProps<T extends keyof HTMLElementTagNameMap> =
  | {
      as: T;
      /**
       * If `true`, the element will be rendered. If `false`, the element will not be rendered.
       */
      rcIf?: boolean;
      /**
       * If has `rcIf` you can't use `rcElse`.
       */
      rcElse?: never;
    }
  | {
      as: T;
      /**
       * If has `rcElse` you can't use `rcIf`.
       */
      rcIf?: never;
      /**
       * If `true`, the element will not be rendered. If `false`, the element will be rendered.
       */
      rcElse?: boolean;
    };

type ElementProps<T extends keyof HTMLElementTagNameMap> = ElementBaseProps<T> &
  ComponentProps<T>;

export function Element<T extends keyof HTMLElementTagNameMap>({
  as,
  children,
  rcIf = true,
  rcElse = false,
  ...props
}: ElementProps<T>) {
  if (rcIf === false || rcElse === true) {
    return null;
  }

  return React.createElement(as, props as ComponentProps<T>, children);
}

export default Element;
Enter fullscreen mode Exit fullscreen mode

Element Props

The Element component accepts the following props:

  • as: The HTML tag name of the element to be rendered.

  • rcIf: If true, the element will be rendered. If false, the element will not be rendered. If rcElse is provided, rcIf cannot be used, and vice versa.

  • rcElse: If true, the element will not be rendered. If false, the element will be rendered. If rcIf is provided, rcElse cannot be used, and vice versa.

  • children: The children of the element. This can be a string, a React element, or an Array of React elements.

Element Usage

The Element component can be used to conditionally render elements based on specific conditions. It can be used in the following ways:

import React from 'react';
import Element from './Element';

export default function Usage() {
  return (
    <Element as="main">
      {/* ✅ Element Component as a with all props */}
      <Element as="a" href="https://www.google.com" target="_blank">
        Google
      </Element>
      {/* ✅ Element Component as h1 with all props */}
      <Element rcIf as="h1">
        Hello, World!
      </Element>
      {/* ✅ Element Component as section with all props */}
      <Element as="section" rcIf={false}>
        Hello, World!
      </Element>
      {/* ✅ Element Component as span with all props */}
      <Element rcElse as="span">
        Hello, World!
      </Element>
      {/* ❌ You can't use rcIf and rcElse together */}
      <Element rcIf as="h4" rcElse={false}>
        Hello, World!
      </Element>
      {/* ✅ Element Component as Input */}
      <Element as="input" type="color" />
      <Element as="input" type="date" />
      <Element as="input" type="datetime-local" />
      <Element as="input" type="email" />
      <Element as="input" type="file" />
      <Element as="input" type="month" />
      <Element as="input" type="number" />
      <Element as="input" type="password" />
      <Element as="input" type="radio" />
      <Element as="input" type="range" />
      <Element as="input" type="search" />
      <Element as="input" type="tel" />
      <Element as="input" type="text" />

      {/* ✅ Element Component as div with inline style */}
      <Element
        as="div"
        style={{
          display: 'flex',
          flexDirection: 'column',
          gap: '10px',
          height: '30vh',
          overflowY: 'auto',
        }}
      >
        {todos.map((todo) => {
          return (
            <Element as="div" key={todo.id}>
              <Element as="input" checked={todo.completed} type="checkbox" />
              <Element as="h2">{todo.title}</Element>
              <Element as="p">
                {todo.completed ? 'Completed' : 'Not completed'}
              </Element>
            </Element>
          );
        })}
      </Element>
    </Element>
  );
}
Enter fullscreen mode Exit fullscreen mode

Features

  • Type Safety: The Element component is built with TypeScript, which allows it to provide a type-safe interface. This helps reduce the risk of unexpected bugs and improves code clarity.

  • Ease of Use: The Element component is easy to use. It provides a straightforward API that allows developers to conditionally render elements based on specific conditions.

  • Flexibility: The Element component is flexible. It can be used to render elements based on a single condition or multiple conditions.

  • Exclusive Usage: If rcIf is provided, rcElse cannot be used, and vice versa. This ensures that only one conditional rendering strategy is employed for each instance of the Element component.

Drawing Inspiration from Angular and Vue

The conditional rendering approach implemented in the Element component draws inspiration from similar concepts in Angular and Vue. Angular developers are familiar with the *ngIf directive, while Vue developers often use the v-if and v-else directives. The Element component adopts a similar philosophy, providing a concise and readable way to conditionally render elements in React.

Conclusion

The Element component is a React component that allows developers to conditionally render elements based on specific conditions. It leverages TypeScript to provide a type-safe interface and improve code clarity.

Feel free to incorporate the Element component into your React projects to simplify conditional rendering and improve the overall maintainability of your codebase.

Thanks for reading! Happy coding!

. . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player