#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)
Я думаю, что есть лучший способ решить эту проблему