Home > Net >  How to make a hook from my code React.js/Next.js?
How to make a hook from my code React.js/Next.js?

Time:05-11

I try to make a hook from my code, but I got the issue. My code from hook file:

    import { useRouter } from "next/router";


    const useCurrentPath = () => {
    const { asPath, locale, defaultLocale } = useRouter();
    if (locale === defaultLocale) return { asPath };

    return `/${locale}${asPath}`;  
    };

    export default useCurrentPath; 

Place where I call it

import { SubHeaderLink, SubHeaderLinks } from "@/components/layout/subHeader/SubHeader";
import { ReactStoryblokComponent, StoryblokLink } from "@/types/storyblok";
import { useStoryblokLinkParser } from "storyblok/useStoryblokLinkParser";
import useCurrentPath from "hooks/useCurrentPath";

type Blok = {
  subHeaderLinks: { _uid: string; linkName: string; href: StoryblokLink }[];
};

const StoryblokSubHeader: ReactStoryblokComponent<Blok> = ({
  blok: { subHeaderLinks },
}) => {
  const { getHref } = useStoryblokLinkParser();
  const getCurrentPath = useCurrentPath();

  return (
    <SubHeaderLinks>
      {subHeaderLinks.map(({ _uid, href, linkName }) => (
        <SubHeaderLink
          key={_uid}
          href={getHref(href)}
          name={linkName}
          isActive={ getCurrentPath() === getHref(href)}
        />
      ))}
      ))
    </SubHeaderLinks>
  );
};

export default StoryblokSubHeader;

on the row

isActive={ getCurrentPath() === getHref(href)}

I got the issue "This expression is not callable. No constituent of type 'string | { asPath: string; }' is callable."

CodePudding user response:

const { asPath, locale, defaultLocale } = useRouter();
if (locale === defaultLocale) return { asPath };

You're destructuring asPath from useRouter(); in the first line, but then your returning it inside an object on the second.

try:

const { asPath, locale, defaultLocale } = useRouter();
if (locale === defaultLocale) return asPath;

Your function should return a string regardless then.

CodePudding user response:

The following line:

const getCurrentPath = useCurrentPath();

assigns the result of calling useCurrentPath to the getCurrentPath constant. That result, based on your hook, is either a string or an object of type { asPath: string }.

That result is not a function and is therefore not callable. And you're calling it inside JSX - in isActive attribute of <SubHeaderLink />).

You probably meant:

const getCurrentPath = useCurrentPath

, because useCurrentPath is callable. Or, alternatively:

const getCurrentPath = () => useCurrentPath()

Another problem is the very fact you're not always returning a string from your custom hook.
I believe you should replace return { asPath } with return asPath, inside your hook, so the hook always returns a string, which is, most likely, what you want.

CodePudding user response:

The issue is that you are returning a string/object from your hook and then trying to invoke it as a funciton.

Minor changes, i would suggest :

  1. You should be returning a string from your hook. Return asPath instead of an object.
    import { useRouter } from "next/router";


    const useCurrentPath = () => {
    const { asPath, locale, defaultLocale } = useRouter();
    if (locale === defaultLocale) return asPath;

    return `/${locale}${asPath}`;  
    };

    export default useCurrentPath; 

  1. Use the string directly instead of trying to invoke an object/string, which is what causes the error.
        <SubHeaderLink
          key={_uid}
          href={getHref(href)}
          name={linkName}
          isActive={ getCurrentPath === getHref(href)}
        />
  • Related