Почему urql делает запрос по неправильному адресу, когда я использую рендеринг на стороне сервера?

#reactjs #graphql #next.js #server-side-rendering #urql

Вопрос:

Я создаю интерфейс своего веб-приложения с помощью NextJS. Мой клиент работает на http://localhost:3000/ , и мой сервер graphql находится на http://localhost:5000/graphql . Поэтому я создавал клиент Urql, и мне нужен рендеринг на стороне сервера. В моем index.tsx я создал клиент urql, используя withUrqlClient, и указал правильный URL-адрес для своего бэкенда:

 const Index = () => {
  return (
    <div>
      <Head>
        <meta
          name="viewport"
          content="minimum-scale=1, initial-scale=1, width=device-width"
        />
      </Head>
      <Navbar />
      <h1>Hello stc</h1>
    </div>
  );
};

// create urql client
export default withUrqlClient((ssrExchange: any) => ({

  url: "http://localhost:5000/graphql",   
  exchanges: [
    dedupExchange,
    cacheExchange({
      updates: {
        Mutation: {
          loginUser: (_result, _args, cache) => {
            customUpdateQuery<LoginMutation, MeQuery>(
              cache,
              { query: MeDocument },
              _result,
              (result, query) => {
                if (result.loginUser.errors) {
                  return query;
                } else {
                  return {
                    me: result.loginUser.user,
                  };
                }
              }
            );
          },
          registerUser: (_result, _args, cache) => {
            customUpdateQuery<RegisterMutation, MeQuery>(
              cache,
              { query: MeDocument },
              _result,
              (result, query) => {
                if (result.registerUser.errors) {
                  return query;
                } else {
                  return {
                    me: result.registerUser.user,
                  };
                }
              }
            );
          },
          .
          .
          .
      },
    }),
    ssrExchange,
    fetchExchange,
  ],
}))(Index);
 

Проблема в том, что когда я захожу на /login страницу (или любую страницу, кроме индекса) и делаю запрос на отправку в форме входа, он делает запрос http://localhost:3000 . Я получаю предупреждение на консоли:

Я не думаю, что эта ошибка в файле login.tsx

Войдите в систему.tsx

 interface FormValues {
  usernameOrEmail: string;
  password: string;
}

// initial values for form
const initialValues: FormValues = {
  usernameOrEmail: "",
  password: "",
};

const loginSchema = yup.object().shape({
  usernameOrEmail: yup.string().required("Required"),
  password: yup.string().required("Required"),
});

const login: React.FC<loginProps> = ({}) => {
  const router = useRouter();
  const [isLoading, setIsLoading] = useState<boolean>(false);
  const [, login] = useLoginMutation();
  return (
    <div>
      <NavBar />

      <Wrapper variant="small">

        <Formik
          initialValues={initialValues}
          onSubmit={async (values: FormValues, { setErrors }) => {
            setIsLoading(true);
            // Make register mutation
            const response = await login({
              details: {
                usernameOrEmail: values.usernameOrEmail,
                password: values.password,
              },
            });
            // Handle errors
            if (response.data?.loginUser.errors) {
              setErrors(toErrorMaps(response.data.loginUser.errors));
            } else {
              // if no errors, re route to home page
              router.push("/");
            }
            setIsLoading(false);

            // Handle errors
            if (response.data?.loginUser.errors) {
              setErrors(toErrorMaps(response.data.loginUser.errors));
            } else {
              // if no errors, re route to home page
              router.push("/");
            }
          }}
          validationSchema={loginSchema}
        >
          {({ isValid, dirty }) => (
            <Form autoComplete="off">
              {/* <LinearProgress /> */}
              <FormikField
                name="usernameOrEmail"
                label="Username or Email"
                type="text"
              />

              <FormikField name="password" label="Password" type="password" />

              <Button
                variant="contained"
                color="primary"
                // disabled={!dirty||  || !isValid}
                disabled={!dirty || !isValid || isLoading}
                type="submit"
                fullWidth
              >
                Login
              </Button>
              {isLoading ? <LinearProgress color="primary" /> : <div></div>}
            </Form>
          )}
        </Formik>
      </Wrapper>
    </div>
  );
};

export default login;



Default Client: No client has been specified using urql's Provider.This means that urql will be 
falling back to defaults including making requests to `/graphql`.
If that's not what you want, please create a client and add a Provider.
 

Кто-нибудь может, пожалуйста, объяснить, что происходит ? Я следовал документации, как она есть: https://formidable.com/open-source/urql/docs/advanced/server-side-rendering/#nextjs

Просто для справки, вот мой _app.tsx

   function MyApp({ Component, pageProps }) {
  return (
    <MuiThemeProvider theme={customTheme}>
      <Component {...pageProps} />
    </MuiThemeProvider>
  );
}

export default MyApp;
 

Есть ли обертка вокруг приложения, которой мне не хватает ?

Комментарии:

1. Вы очистили свой кэш?

2. Я сделал да…. Он все еще делает запрос по неправильному адресу

3. Вместо этого вы должны обернуть свой _app компонент withUrqlClient , чтобы он был доступен для всех страниц.

Ответ №1:

Упаковка экспорта компонентов входа в систему следующим образом хорошо сработала для меня.

export default withUrqlClient((ssrExchange: any) => ({...})(Login)

Я думаю, что есть лучший способ решить эту проблему