Skip to content

Instantly share code, notes, and snippets.

@thepuskar
Created August 21, 2023 06:25
Show Gist options
  • Save thepuskar/8bc9c601b869efc243b031ec288d47c6 to your computer and use it in GitHub Desktop.
Save thepuskar/8bc9c601b869efc243b031ec288d47c6 to your computer and use it in GitHub Desktop.
Utility component for conditional rendering in React js
import { GoalLegend } from "./components/switch";
function App() {
return (
<div className="App">
<GoalLegend goal={0} />
</div>
);
}
export default App;
import { Case, Default, Switch } from "./Switch";
interface IGoalProps {
goal: number;
}
export const GoalLegend = ({ goal }: IGoalProps) => {
return (
<>
<Switch>
<Case condition={goal < 30}>There is still some work to do</Case>
<Case condition={goal >= 30 && goal < 60}>You are almost there</Case>
<Default>You reach your goal</Default>
</Switch>
</>
);
};
import React, { ReactElement, ReactNode } from "react";
interface CaseProps {
condition: boolean;
children: ReactNode;
}
/**
* React component that represents a case within a Switch component.
*
* @component
* @param {Object} props - The component's props.
* @param {boolean} props.condition - The condition to evaluate for this case.
* @param {ReactNode} props.children - The content to render when the condition is true.
* @returns {ReactNode} The content to be conditionally rendered.
*/
const Case = ({ children }: CaseProps): ReactElement => {
return <>{children}</>;
};
/**
* React component that represents a default case within a Switch component.
*
* @component
* @param {Object} props - The component's props.
* @param {ReactNode} props.children - The content to render when no Case condition matches.
* @returns {ReactNode} The content to be rendered when no Case condition matches.
*/
const Default = ({ children }: { children: ReactNode }): ReactElement => {
return <>{children}</>;
};
/**
* React component that conditionally renders its children based on provided cases.
*
* @component
* @example
* // Example usage of the Switch component:
* <Switch>
* <Case condition={someCondition}>
* <div>This content is displayed when someCondition is true.</div>
* </Case>
* <Default>
* <div>This content is displayed when no Case condition matches.</div>
* </Default>
* </Switch>
*
* @param {Object} props - The component's props.
* @param {ReactNode} props.children - The children to be conditionally rendered.
* @returns {ReactNode} The matched Case or Default child to render.
*/
const Switch = ({ children }: { children: ReactNode }) => {
let matchChild: any = null;
let defaultChild: any = null;
React.Children.forEach(children, (child) => {
if (
child &&
React.isValidElement(child) &&
!matchChild &&
child.type === Case
) {
const { condition } = child.props as CaseProps;
const conditionResult = Boolean(condition);
if (conditionResult) {
matchChild = child;
}
} else if (
child &&
React.isValidElement(child) &&
!defaultChild &&
child.type === Default
) {
defaultChild = child;
}
});
return matchChild ?? defaultChild ?? null;
};
export { Case, Default, Switch };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment