Samke11
Samke11

Reputation: 525

Next.js - Can we call custom hooks in GetStaticProps()

Is there any way for us to use the custom hook in getStaticProps(). The reason for this, is beacuse, we are using the Contentful CMS to fetch the data, from the Delivery API, and it is easier for us to have custom hooks to fetch certain data.

Now when we call, for example useHomePageData in getStaticProps() function, we get the error when trying to use simple object destructing to get the data.

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 
1. You might have mismatching versions of React and the renderer (such as React DOM) 
2. You might be breaking the Rules of Hooks 
3. You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.

This is the code we have in getStaticProps()

export function getStaticProps() {
const { data, isPending, error } = useFetchPagesProps('phasePage');
const { name, title, slug, sections } = data;

return {
 props: {
     name,
     title,
     slug,
     sections
  }
 }
}

I know what this error means, but still does someone know for example any npm library or something like that, so that we can use this custom-hook?

P.S: We are also using useEffect() inside the custom-hook so that can cause the problems I think

Upvotes: 1

Views: 6066

Answers (3)

Yilmaz
Yilmaz

Reputation: 49321

custom hooks are NOT any functions that you prefix their name with use. custom hooks are functions that use one of the react hooks. If you check the source code of any library's use functions, you will see they are using one of the react hooks.

enter image description here

Before we execute any react hooks, it first calls resolveDispatcher

function resolveDispatcher() {
  var dispatcher = ReactCurrentDispatcher.current;

  {
    if (dispatcher === null) {
      error('Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + ' one of the following reasons:\n' + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + '2. You might be breaking the Rules of Hooks\n' + '3. You might have more than one copy of React in the same app\n' + 'See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.');
    }
  } // Will result in a null access error if accessed outside render phase. We
  // intentionally don't throw our own error because this is in a hot path.
  // Also helps ensure this is inlined.
  return dispatcher;
}

if your custom hook does not use any of react hooks, it is just a plain function.

Upvotes: 0

Taghi Khavari
Taghi Khavari

Reputation: 6582

This is against React Hooks rules and its best practices, and you have to avoid this mentality at all costs, but there are sometimes that you just want to do it wrong ;). in those circumstances you can create a kinda global variable and trick the React to think that you're obeying the rules but clearly you're not :).

the code would be something like this:

//use the hook in one the parents component which you know that would be initialized earlier
//for example maybe _app.js file

let hackTheHooksRules;
function MyApp({ Component, pageProps }) {
  hackTheHooksRules = useFetchPagesProps("phasePage");
  return <Component {...pageProps} />
}
export default MyApp;
export hackTheHooksRules;

and in the destination where you want to use it, you should do something like this:

import {hackTheHooksRules} from 'path-to-that-file'
export function getStaticProps() {
  const { data, isPending, error } = hackTheHooksRules || {};
  const { name, title, slug, sections } = data;

  return {
    props: {
      name,
      title,
      slug,
      sections
    }
  };
}

NOTE: again this is not recommended but sometimes The heart wants what it wants and who are you to blame it 😅

here is the the rules of hooks which you should try to obey them: reactjs.org/docs/hooks-rules.html

Upvotes: 1

Ivan V.
Ivan V.

Reputation: 8081

getStaticProps technically has nothing to do with React. In essence that is just a function with a special meaning and functionality to the Next.js framework itself. So no, you can't use hooks in there (at least not the ones that use setState useEffect etc.. inside of them.

Upvotes: 5

Related Questions