skip to Main Content

Is it possible to assign the hook return function to a render map in React? The following example includes the socialAuthMethodsMap map with the onClick parameter. I want to assign the signInWithApple function from useFirebaseAuth hook, but it breaks the essential React hook laws. Is there any alternatives?

import {FunctionComponent, MouseEventHandler} from 'react'
import { IconProps } from 'react-feather'

type TSocialAuthMethodData = {
    code: string
    logo?: string | FunctionComponent<IconProps>
    onClick: MouseEventHandler<HTMLButtonElement>
}

// const { signInWithApple } = useFirebaseAuth()

export const socialAuthMethodsMap: Array<TSocialAuthMethodData> = [
    {
        code: 'apple',
        logo: '/assets/icons/social/apple.svg',
        onClick: signInWithApple,
    },
    {
        code: 'google',
        logo: '/assets/icons/social/google.svg',
        onClick: () => null,
    },
    {
        code: 'github',
        logo: '/assets/icons/social/github.svg',
        onClick: () => null,
    },
]

Render function

<div>
            {socialAuthMethodsMap.map((socialAuthMethod) => (
                <SocialAuthButton
                    key={socialAuthMethod.code}
                    title={socialAuthMethod.code}
                    logo={socialAuthMethod.logo}
                    onClick={socialAuthMethod.onClick}
                />
            ))}
        </div>

2

Answers


  1. you have to call the hook in the component. The returned function signInWithApple you can do whatever you want with.

    So here if you move socialAuthMethodsMap into the component as well as the hook then should be good.

    Something like this

    
    const MyComponent = () => {
      const { signInWithApple } = useFirebaseAuth();
    
      const socialAuthMethodsMap: Array<TSocialAuthMethodData> = [
        {
          code: "apple",
          logo: "/assets/icons/social/apple.svg",
          onClick: signInWithApple,
        },
        {
          code: "google",
          logo: "/assets/icons/social/google.svg",
          onClick: () => null,
        },
        {
          code: "github",
          logo: "/assets/icons/social/github.svg",
          onClick: () => null,
        },
      ];
    
      return (
        <div>
          {socialAuthMethodsMap.map((socialAuthMethod) => (
            <SocialAuthButton
              key={socialAuthMethod.code}
              title={socialAuthMethod.code}
              logo={socialAuthMethod.logo}
              onClick={socialAuthMethod.onClick}
            />
          ))}
        </div>
      );
    };
    
    

    Or if you need to export it, would probably make a hook and have the array as the result.

    export const useSocialAuthData = () => {
      const { signInWithApple } = useFirebaseAuth();
    
      const socialAuthMethodsMap: Array<TSocialAuthMethodData> = [
        {
          code: "apple",
          logo: "/assets/icons/social/apple.svg",
          onClick: signInWithApple,
        },
        {
          code: "google",
          logo: "/assets/icons/social/google.svg",
          onClick: () => null,
        },
        {
          code: "github",
          logo: "/assets/icons/social/github.svg",
          onClick: () => null,
        },
      ];
    
      return socialAuthMethodsMap;
    };
    
    const MyComponent = () => {
      const socialAuthMethodsMap = useSocialAuthData();
    
      return (
        <div>
          {socialAuthMethodsMap.map((socialAuthMethod) => (
            <SocialAuthButton
              key={socialAuthMethod.code}
              title={socialAuthMethod.code}
              logo={socialAuthMethod.logo}
              onClick={socialAuthMethod.onClick}
            />
          ))}
        </div>
      );
    };
    
    
    
    Login or Signup to reply.
  2. You are getting the error because you are trying to use signInWithApple directly as the onClick event handler, however you cannot directly use hooks outside of functional components or custom hooks.

    To solve this problem you can create a wrapper function OnClickHandler that invokes the hook and use this function as onClick event handler.

    I hope you had imported all necessary libraries and packages, and making the given changes in code may solve your issue .

     import {FunctionComponent, MouseEventHandler} from 'react'
     import { IconProps } from 'react-feather'
    
     type TSocialAuthMethodData = {
     code: string
     logo?: string | FunctionComponent<IconProps>
     onClick: MouseEventHandler<HTMLButtonElement>
     }
    
    
       //handler function to invoke the signInWithApple on onClick event
      const OnClickHandler=()=>{
      const { signInWithApple } = useFirebaseAuth();
      signInWithApple();
     }
    
     export const socialAuthMethodsMap: Array<TSocialAuthMethodData> = [
     {
        code: 'apple',
        logo: '/assets/icons/social/apple.svg',
        onClick: OnClickHandler,   // use the handler function 
        
     },
     {
        code: 'google',
        logo: '/assets/icons/social/google.svg',
        onClick: () => null,
     },
     {
        code: 'github',
        logo: '/assets/icons/social/github.svg',
        onClick: () => null,
     },
     ]
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search