问题描述
我正在使用 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,cache) => {
customUpdateQuery<RegisterMutation,query) => {
if (result.registerUser.errors) {
return query;
} else {
return {
me: result.registerUser.user,.
.
.
},}),ssrExchange,fetchExchange,],}))(Index);
问题是,当我转到 /login
页面(或除索引之外的任何页面)并在登录表单上提出提交请求时,它会向 http://localhost:3000
提出请求。我在控制台上收到警告:
我认为该错误不在 login.tsx 中
Login.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;
是否有我缺少的应用程序的包装器?
解决方法
如下包装登录组件导出对我来说效果很好。
export default withUrqlClient((ssrExchange: any) => ({...})(Login)
我认为有更好的方法来解决它