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 :
- 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;
- 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)}
/>