Skip to content

Instantly share code, notes, and snippets.

@shepardm7
Created June 19, 2023 16:13
Show Gist options
  • Save shepardm7/69081cac8022ecd5fc69f5aeb868717f to your computer and use it in GitHub Desktop.
Save shepardm7/69081cac8022ecd5fc69f5aeb868717f to your computer and use it in GitHub Desktop.
React conditional hook component factory
import {useState} from "react";
interface Opts<TPropsHook extends Record<string, any>, THookReturn extends TPropsHook> {
componentName: string;
useConditionalHook: (props: TPropsHook) => THookReturn | null;
WrappedComponent: (props: THookReturn) => JSX.Element;
ComponentForNull?: (props: TPropsHook) => JSX.Element;
}
const conditionalHookFactory = <TPropsHook extends Record<string, any>, THookReturn extends TPropsHook>({
componentName, useConditionalHook, WrappedComponent, ComponentForNull
}: Opts<TPropsHook, THookReturn>) => {
const WrapperComponent: React.FC<TPropsHook> = (props) => {
const propsToPass = useConditionalHook(props);
if (propsToPass === null) {
if (ComponentForNull) {
return <ComponentForNull {...props} />;
}
return <></>;
}
return <WrappedComponent {...propsToPass} />;
}
(WrappedComponent as any).displayName = componentName;
return WrapperComponent;
}
export interface TestProps {
greeting: string;
}
const TestComp = conditionalHookFactory({
componentName: "TestComp",
useConditionalHook: (props: TestProps) => {
const [number] = useState(Math.floor(Math.random() * 10));
if (number < 5) {
return null;
}
return { number, ...props };
},
WrappedComponent: ({ greeting, number }) => {
return (
<div>
{greeting} {number}
</div>
)
},
ComponentForNull: () => (<div></div>)
});
export default TestComp;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment