Skip to content

Instantly share code, notes, and snippets.

@baliyan9887
Last active March 15, 2024 21:28
Show Gist options
  • Save baliyan9887/67d44483672c61b0d0a78fce53b56bfa to your computer and use it in GitHub Desktop.
Save baliyan9887/67d44483672c61b0d0a78fce53b56bfa to your computer and use it in GitHub Desktop.
React Conditional Rendering Context

React Conditional Rendering Context

This React utility provides a flexible and efficient way to handle conditional rendering within your React applications. The Show component along with its child components Show.When, Show.ElseIf, and Show.Else offers a clean syntax for rendering components based on boolean conditions, akin to if-else statements in traditional programming.

How It Works:

  • Show: Acts as a context provider that tracks whether any of its children have been rendered. It ensures that only one child (the first truthy condition) gets rendered, similar to how an if-else-if chain works.
  • Show.When: Renders its children if the provided isTrue prop is truthy and none of the preceding Show.When or Show.ElseIf components have rendered.
  • Show.ElseIf: An alias to Show.When, providing semantic clarity in cases involving multiple conditions. Functions identically to Show.When.
  • Show.Else: Renders its children if none of the preceding Show.When or Show.ElseIf components have rendered.

Key Features:

  • Contextual Awareness: Leverages React context to keep track of rendering state, ensuring that only one child component or set of components is rendered.
  • Semantic Clarity: Offers clear, logical structuring for conditional rendering that mirrors traditional control flow statements, making your components more readable and maintainable.
  • Flexibility: Easily integrates into existing React applications, supporting both simple and complex conditional rendering logic without additional overhead.

Usage Example:

<Show>
  <Show.When isTrue={condition1}>
    <ComponentForCondition1 />
  </Show.When>
  <Show.ElseIf isTrue={condition2}>
    <ComponentForCondition2 />
  </Show.ElseIf>
  <Show.Else>
    <DefaultComponent />
  </Show.Else>
</Show>

This setup allows for intuitive conditional rendering based on the truthiness of condition1 and condition2, falling back to DefaultComponent if neither condition is met.

import React, { createContext, useContext, ReactNode, useMemo } from 'react';
/**
* Props for conditional rendering components.
*/
interface ConditionalProps {
children: ReactNode;
}
/**
* Props for the When component.
*/
interface WhenProps extends ConditionalProps {
/**
* Boolean condition determining whether to render children.
*/
isTrue: boolean;
}
/**
* Context for managing show/hide state.
*/
const ShowContext = createContext<{ rendered: boolean; setRendered: (rendered: boolean) => void } | undefined>(undefined);
/**
* Component for conditional rendering when a condition is true.
* @param {WhenProps} props - Component props.
* @returns {ReactNode} - Rendered component.
*/
const When: React.FC<WhenProps> = ({ isTrue, children }) => {
const context = useContext(ShowContext);
if (!context) throw new Error('<Show.When> must be used within a <Show> component');
const shouldRender = isTrue && !context.rendered;
if (shouldRender) context.setRendered(true);
return shouldRender ? <>{children}</> : null;
};
/**
* Component for conditional rendering when a condition is true, used as an alias for When.
* @param {WhenProps} props - Component props.
* @returns {ReactNode} - Rendered component.
*/
const ElseIf: React.FC<WhenProps> = ({ isTrue, children }) => <When isTrue={isTrue}>{children}</When>;
/**
* Component for conditional rendering when no previous conditions are met.
* @param {ConditionalProps} props - Component props.
* @returns {ReactNode} - Rendered component.
*/
const Else: React.FC<ConditionalProps> = ({ children }) => {
const context = useContext(ShowContext);
if (!context) throw new Error('<Show.Else> must be used within a <Show> component');
return !context.rendered ? <>{children}</> : null;
};
/**
* Component for managing conditional rendering.
* @param {ConditionalProps} props - Component props.
* @returns {ReactNode} - Rendered component.
*/
const Show: React.FC<ConditionalProps> & { When: React.FC<WhenProps>; ElseIf: React.FC<WhenProps>; Else: React.FC<ConditionalProps> } = ({ children }) => {
const [rendered, setRendered] = React.useState(false);
const value = useMemo(() => ({ rendered, setRendered }), [rendered]);
return <ShowContext.Provider value={value}>{children}</ShowContext.Provider>;
};
Show.When = When;
Show.ElseIf = ElseIf; // Else-If functionality integrated as an alias of When but semantically different
Show.Else = Else;
export default Show;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment