typescript 如何将NextJS www.example.com输入router.query.id为字符串?

06odsfpq  于 2023-06-07  发布在  TypeScript
关注(0)|答案(1)|浏览(119)

我是TypeScript的新手,也使用T3堆栈(React Query / Tanstack Query)。我尝试将companyId输入为string,这样我就不必在以后的代码中每次使用它时都输入companyId as string,但我不知道如何最好地做到这一点,或者这个堆栈的最佳实践是什么。我习惯了使用普通的JavaScript和useEffects来进行API调用(可能会编写更糟糕的代码)。

  • 注意:以下代码存在于/pages/companies/[id].tsx *

下面是我的第一次尝试,但是我在“const { data:company}...",这是有道理的:

const CompanyPage: NextPage = () => {
  const router = useRouter()

  const companyId = router.query.id
  if (!companyId || Array.isArray(companyId)) return <div>Loading...</div> // have to check for Array.isArray because of NextJS/Typescript bug

  const { data: company } = api.companies.getSingleById.useQuery({companyId: companyId});
  if (!company ) return <div>Loading...</div>

  ...
  return (...)

我尝试执行以下操作,但不被允许,因为www.example.com中的companyId的类型router.query.id是string | string[] | undefined

const CompanyPage: NextPage = () => {
  const router = useRouter()

  const companyId: string = router.query.id // Type 'string | string[] | undefined' is not assignable to type 'string'

  const { data: company } = api.companies.getSingleById.useQuery({companyId: companyId});
  if (!company ) return <div>Loading...</div>

  ...
  return (...)

更新:

我现在把它改成了下面的,这似乎行得通,但感觉不太对,这是正确的做事方式。(使用这种方法,我只需要写一次companyId as string,这很好。

const CompanyPage: NextPage = () => {
  const router = useRouter()

  const companyId = router.query.id
  const { data: company } = api.companies.getSingleById.useQuery({companyId: companyId as string});

  if (!companyId || Array.isArray(companyId)) return <div>Loading...</div> // have to check for Array.isArray because of NextJS/Typescript bug
  if (!company ) return <div>Loading...</div>

  ...
  return (...)

回复:

感谢Fabio接受的答案。
我正在将router.query解构为其他路由上的多个变量,因此这是一个基于接受的答案的示例:

const { companyId, locationId } = useMemo(() => ({
  companyId: router.query?.companyId?.toString() ?? "",
  locationId: router.query?.locationId?.toString() ?? "",
}), [router.query?.companyId, router.query?.locationId]);
j5fpnvbx

j5fpnvbx1#

您可以将optional chainingnullish coalescing与查询参数的toString()方法结合使用,以下是基于您的代码片段的示例:

const CompanyPage: NextPage = () => {
  const router = useRouter();

  // this result will be of type string
  const companyId = useMemo(() => {
    return router.query?.id?.toString?.() ?? "";
  }, [router.query?.id]);

  const { data: company } = api.companies.getSingleById.useQuery({
    companyId: companyId,
  });

  if (!company) return <div>Loading...</div>;

  return; // ...
};

查询参数类型为string | string[]的原因是,如果你有一个catch-all段,每个url部分将被/分割,并以数组的形式呈现给你。

示例

如果您有路由/some-segment/[...href],URL为/some-segment/200/my-post,则适用以下内容:

  • href查询变量的内容为["200", "my-post"]
  • 调用href?.toString?.()将返回/some-segment/200/my-post

相关问题