首页 > 解决方案 > 错误:无效的钩子调用(Codegen & Apollo & Next.js)

问题描述

我尝试使用 Codegen 生成的钩子来进行注册突变:

export default function signUpComponent() {
  const { register, handleSubmit } = useForm<SignUpFormData>();
  const [signUpMutation, { data, loading, error }] = useSignUpMutation();
  const { setToken } = useAuth();
  const onSubmit: SubmitHandler<SignUpFormData> = async (data) => {
    try {
      const result = await await signUpMutation({
        variables: {
          input: data,
        },
      });

      if (result.errors) {
        throw new Error('Cannot sign up' + result.errors);
      }
      if (result.data) {
        setToken(result.data.signUp.token);
        console.log(result.data.signUp.token);
      }
    } catch (e) {
      throw new Error(e);
    }
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label>First Name:</label>
      <input
        className='w-1/4'
        {...register('firstName', { required: true, maxLength: 20 })}
      />
      <label>Last Name:</label>
      <input
        className='w-1/4'
        {...register('lastName', { required: true, pattern: /^[A-Za-z]+$/i })}
      />
      <label>Email:</label>
      <input
        className='w-1/4'
        {...register('email', {
          required: true,
          pattern:
            /^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/,
        })}
      />
      <label>Password:</label>
      <input
        className='w-1/4'
        {...register('password', { required: true, maxLength: 15 })}
      />
      <input type='submit' />
    </form>
  );
}

但是在 http://localhost:3000/signup 得到了这个错误:

Unhandled Runtime Error
Error: 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.

我已经尝试了很多方法,比如将它包装在 useEffect 或 useCallback 中(只需遵循其他问题的解决方案,虽然不知道为什么),或者使用异步 IIFE,仍然无法解决。

这是我的仓库:https ://github.com/Jocelyn59435/Trackky_frontend

任何帮助表示赞赏。

标签: reactjsnext.jsapollo-clientgraphql-codegen

解决方案


错误日志是真的,我打破了钩子规则,在函数而不是函数组件中调用它。

在 useApollo.tsx 下:

import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';
import useAuth from './useAuth';

const httpLink = new HttpLink({
  uri: 'https://trackkybackend.herokuapp.com/graphql',
});

const authLink = setContext((_, { headers }) => {
  //get the authentication token from cookies

  const userToken = useAuth(); ==============> HOOK!!

  //return headers to the context so httpLink can read them
  return {
    headers: {
      ...headers,
      authorization: userToken ? `Bearer ${userToken}` : '',
    },
  };
});

export const useApollo = new ApolloClient({
  cache: new InMemoryCache(),
  link: authLink.concat(httpLink),
  ssrMode: typeof window === 'undefined',
});

这样的痛苦。


推荐阅读