Next.js Discord

Discord Forum

Better approach of component implementation

Answered
Rhinelander posted this in #help-forum
Open in Discord
RhinelanderOP
First approach
type SocialProvider = "apple" | "google"

type SocialSigninButtonProps = {
  provider: SocialProvider;
  buttonText: string;
  icon: React.ReactNode;
  callbackURL?: string;
};

export function SocialSigninButton({
  provider,
  buttonText,
  icon,
  callbackURL = "/",
}: SocialSigninButtonProps) {
  return (
    <Button
      type="button"
      variant="outline"
      className="w-full"
      onClick={async () => {
        await signIn.social({
          provider,
          callbackURL,
        });
      }}
    >
      {icon}
      {buttonText}
    </Button>
  );
}

export const AppleIcon = () => (
... svg
);

export const GoogleIcon = () => (
... svg
);


Second approach - each component individually
export function AppleButton() {
  return (
    <Button
      type="button"
      variant="outline"
      className="w-full"
      onClick={async () => {
        await signIn.social({
          provider: "apple",
          callbackURL: "/",
        });
      }}
    >
      <svg ...stuff />
      Login with Apple
    </Button>
  );
}


Which approach is better? Is there third approach? What would senior enterprise developer choose?
Answered by Asian black bear
Composition is the way to go, yes.

But your approach allows for props that make no sense which is often not intended. For example picking Apple as the provider but expecting the consumer of the component to provide an icon themselves which could be Google.

Let the button pick the right icon based on provider and only use the icon prop if there is REALLY a need to override it. Similarly the button could deduce the text itself and not expect others to provide it.

Only use props in this example if it truly makes sense for the callee to customize the look with composition.
View full answer

1 Reply

Asian black bear
Composition is the way to go, yes.

But your approach allows for props that make no sense which is often not intended. For example picking Apple as the provider but expecting the consumer of the component to provide an icon themselves which could be Google.

Let the button pick the right icon based on provider and only use the icon prop if there is REALLY a need to override it. Similarly the button could deduce the text itself and not expect others to provide it.

Only use props in this example if it truly makes sense for the callee to customize the look with composition.
Answer