我正在尝试遵循 Ben Awad 的 lireddit 教程。
他展示了如何制作实用程序文件来显示应用程序中的任何身份验证错误。
我认为自从他制作视频以来,下一个/路由器的情况可能已经改变。我正在努力找出一种方法来使用路由器以这种方式在组件内部的钩子内部重定向。
我无法将 useRouter 钩子放在 exchangeError 中 - 我认为原因是当我想在其他组件中使用 exchangeError 时,该钩子不再位于顶层,但是我不知道如何让exchangeError在没有它的情况下工作,或者适应next/router的更新版本。
我最好的尝试(我知道我不能这样使用它)如下:
import { dedupExchange, fetchExchange, createClient, Exchange } from "urql";
import { pipe, tap } from 'wonka'
import { useRouter } from 'next/router'
const errorExchange: Exchange = ({ forward }) => (ops$) => {
// where can i put this
// const Router = useRouter();
return pipe(
forward(ops$),
tap(({ error }) => {
if (error?.message.includes("not authenticated")) {
// Router.replace("/auth/login");
}
})
);
};
Ben 在 lireddit 上发布的版本是:
const errorExchange: Exchange = ({ forward }) => (ops$) => {
return pipe(
forward(ops$),
tap(({ error }) => {
if (error?.message.includes("not authenticated")) {
Router.replace("/login");
}
})
);
};
整个实用程序文件如下:
import { dedupExchange, fetchExchange, createClient, Exchange } from "urql";
import { cacheExchange } from '@urql/exchange-graphcache'
import { MeDocument, LoginMutation, RegisterMutation, MeQuery, LogoutMutation } from "../generated/graphql"
import { betterUpdateQuery } from '../utils/betterUpdateQuery'
import { pipe, tap } from 'wonka'
import { useRouter } from 'next/router'
const errorExchange: Exchange = ({ forward }) => (ops$) => {
// where can i put this
// const Router = useRouter();
return pipe(
forward(ops$),
tap(({ error }) => {
if (error?.message.includes("not authenticated")) {
// Router.replace("/auth/login");
}
})
);
};
export const createUrqlClient = (ssrExchange: any) => (
{
url: 'http://localhost:4000/graphql',
fetchOptions: {
credentials: 'include' as const,
},
exchanges: [
dedupExchange,
cacheExchange({
updates: {
Mutation: {
logout: (_result, args, cache, info) => {
betterUpdateQuery<LogoutMutation, MeQuery>(
cache,
{query: MeDocument},
_result,
(result, query) => ({me: null})
)
},
login: (_result, args, cache, info) => {
betterUpdateQuery<LoginMutation, MeQuery>(
cache,
{ query: MeDocument },
_result,
(result, query) => {
if (result.login.errors) {
return query;
} else {
return {
me: result.login.user,
};
}
}
);
},
register: (_result, args, cache, info) => {
betterUpdateQuery<RegisterMutation, MeQuery>(
cache,
{ query: MeDocument },
_result,
(result, query) => {
if (result.register.errors) {
return query;
} else {
return {
me: result.register.user,
};
}
}
);
},
},
},
}),
errorExchange,
ssrExchange,
fetchExchange,
],
}
)
然后,在创建帖子表单中,此实用程序的使用如下:
import { withUrqlClient } from "next-urql";
import { useRouter } from "next/router";
import React from "react";
import { useCreatePostMutation } from "../generated/graphql";
import { createUrqlClient } from "../utils/createUrqlClient";
import { useIsAuth } from "../utils/useIsAuth";
const CreatePost: React.FC<{}> = ({}) => {
// const router = useRouter();
// useIsAuth();
const [, createPost] = useCreatePostMutation();
return (
<Layout variant="small">
<Formik
initialValues={{ title: "", text: "" }}
onSubmit={async (values) => {
const { error } = await createPost({ input: values });
if (!error) {
router.push("/");
}
}}
>
export default withUrqlClient(createUrqlClient)(CreatePost);