useSelector Hook – Invalid hook call. Hooks can only be called inside of the body of a function component

Why i got this error?

Error: Invalid hook call. Hooks can only be called inside of the body
of a function component.

Here’s my code in useSession.js:

import { useSelector } from 'react-redux';

export const useSession = () => {  
  const session = useSelector(state => state.session)
  return session
}

And code in Auth.js

import { useSession } from './useSession';

export const getServerSideProps = options => gssp => {

    const { signedIn, redirectTo } = options;

    return async ctx => {
      const session = useSession();

      if (signedIn && !session) {
        return {
          redirect: {
            destination: redirectTo || '/login',
            permanent: false,
          }
        }
      }

      const result = await gssp(ctx);

      return {
        ...result,
        props: {
          ...result.props,
          session,
        },
      }
    }
  };

>Solution :

You are breaking the rules of hooks. Namely Don’t call Hooks from regular JavaScript functions. You can only use a hook from synchronous render of a react functional component. But here you are calling a hook from a plain javascript function that could be executed at any time.

To fix this you’ll have to move the hook to the root level of your component.

For example:

function MyComp() {
  const session = useSelector(state => state.session)
  return <></>
}

If you want to encapsulate that logic into something reusable, you can make a custom hook.

export const useSession = () => { // note the name starts with `use`.
  const session = useSelector(state => state.session)
  return session
}

Which then must obey the rules of hooks itself:

function MyComp() {
  const session = useSession()
  return <></>
}

Leave a Reply