Skip to content

Instantly share code, notes, and snippets.

@cullylarson
Last active May 10, 2024 17:12
Show Gist options
  • Save cullylarson/3d0ac6f087ce839c1b3566e6c26e4868 to your computer and use it in GitHub Desktop.
Save cullylarson/3d0ac6f087ce839c1b3566e6c26e4868 to your computer and use it in GitHub Desktop.

Original Question

React problem: I want to use a feature flag to call one of two React hooks - an old one, or a new one that will soon replace it.

But, React hooks shouldn't be called conditionally.

Options:

  1. Ignore the ESLint rule and call the hooks conditionally.

  2. Call both hooks, even though I only want to call one.

I don't like either option.

c.f. https://twitter.com/housecor/status/1788655496313930215

Solution

Another solution is to create a private version of the component that takes the hook itself as a prop. Then create an exported "wrapper" component that renders the private component and passes a different version of the hook depending on the feature flag.

If you set a key on the component that changes depending on the feature flag, React will re-mount it and you won't run into issues with the hook changing.

import { type UseHook } form "./useHookShared";
import { useHookOld } from "./useHookOld";
import { useHookNew } from "./useHookNew";
type MyComponentProps = {
id: string;
variant?: "default" | "bold",
}
export function MyComponent(props: MyComponentProps) {
const featureFlag = useFeatureFlag();
return featureFlag
? <MyComponentImplementation key="feature-on" {...props} useHook={useHookNew} />
: <MyComponentImplementation key="feature-off" {...props} useHook={useHookOld} />
}
type MyComponentImplementationProps = MyComponentProps & {
useHook: UseHook;
}
function MyComponentImplementation({
useHook,
id,
variant = "default"
}: MyComponentImplementationProps) {
const result = useHook();
// ...
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment