2

我正在使用 NextJs 构建我的 Web 应用程序的前端。我的客户端正在运行,http://localhost:3000/而我的 graphql 服务器位于http://localhost:5000/graphql. 所以我正在创建 Urql 客户端,我想要服务器端渲染。在我的 index.tsx 中,我使用 withUrqlClient 创建了 urql 客户端,并为我的后端指定了正确的 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;

我缺少的应用程序是否有包装器?

4

2 回答 2

0

遇到同样的问题,花了很多时间却无法解决。我通过withUrqlClient在应用程序组件上使用来解决它,该组件_app.tsx破坏了目的并且不允许选择页面到 ssr 与否。

于 2022-02-07T22:24:33.483 回答
0

如下包装登录组件导出对我来说效果很好。

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

我认为有更好的方法来解决它

于 2021-08-02T20:43:07.917 回答