路由器道具和自定义道具与打字稿反应路由器dom用于功能组件

Posted

技术标签:

【中文标题】路由器道具和自定义道具与打字稿反应路由器dom用于功能组件【英文标题】:router props and custom props with typescript react router dom for functional components 【发布时间】:2021-07-01 15:37:34 【问题描述】:

如标题中所述,我想导入我的组件反应路由器道具和自定义道具。

我的路线如下所示:

<Route
  exact
  path="/logon/:name"
  render=(p)=>(<Content/>)>
</Route>

在这里我得到这个错误: 类型“”缺少“CompProps”类型的以下属性:名称、历史记录、位置、匹配

错误来自我的组件,如下所示:

import RouteComponentProps from "react-router-dom";

interface CompProps extends RouteComponentProps 
  name: string;

export const Content: React.FC<CompProps> = (
  name,
  match,
) => 
  return (
    <section>
      <p>test</p>
    </section>
  );
;

我是 TS 的初学者,但我认为 RouteComponentProps 应该包含(名称、历史、位置)为什么 TS 会向我抛出错误。 将自定义道具和路由器道具传递给组件的最佳做法是什么?

这是错误的屏幕截图

【问题讨论】:

【参考方案1】:

嗯,您的操作似乎是正确的,我们可以获取错误的屏幕截图吗?

这是我通常做的。

type Props =  id: string ;

function Content( name, match : RouteComponentProps<Props>) 
  return (
    <section>
      <p>Got match: match.params.id on name: name</p>
    </section>
  );

将点差改为

render=(p)=&gt;(&lt;Content ...p name="name" /&gt;)&gt;

RouteComponentProps 是否已经暴露了name?所以你只想删除它并做

function Content( name, match : RouteComponentProps) 
  return (
    <section>
      <p>Got match: match.params.id on name: name</p>
    </section>
  );

【讨论】:

我按要求添加了屏幕截图。 是的,只要render=(p)=&gt;(&lt;Content/&gt;)&gt; 只需添加评论,您将name 声明为ContentProps,但从未将其传递给&lt;Content /&gt; name @ 并且只需执行 Content( name, match : RouteComponentProps) 或明确传递 name 就像 &lt;Content name="name" ...p /&gt; 有 useLocation 或 useHistory 等辅助函数,这样我也可以获得道具。但这是最好的做法。意味着我应该只在与 component=Content 相关的情况下导入 RouteComponentProps 但是我如何将自定义道具传递给我的 Content 组件? 谢谢,名称 props 是不需要的,因为 react 路由器在之前的路由中拾取它。我对 RouteComponentProps 感到困惑,但是这样我得到了一切。路由器道具和自定义道具。谢谢!【参考方案2】:

当你使用Route.render 时,你需要将它提供的props 传播到你的组件上,否则当Content 组件渲染时它们不会出现。在你的代码中,改变这个:

<Route
  exact
  path="/logon/:name"
  render=(p)=>(<Content/>)>
</Route>

到这里

<Route
  exact
  path="/logon/:name"
  render=(p)=>(<Content ...p />)>
</Route>

【讨论】:

但是当我用 TS 传播道具时,我在路线上收到另一个错误 => 类型 ' history: History; 中缺少属性“名称”;位置:位置;匹配:匹配;静态上下文?:静态上下文 |不明确的; ' 但在类型 'CompProps'.ts(2741) Content.tsx(5, 3) 中是必需的:'name' 在此处声明。【参考方案3】:

由于“名称”是一个路径参数,它应该只能通过匹配对象访问。

您正在使用您的名称-Property 扩展 RouterProps。这似乎没问题。但是将您的功能组件声明为

export const Content: React.FC<CompProps> = (
   name,
   match,
) => 
   ...

似乎是错误的。我希望将组件定义为

export const Content: React.FC<CompProps> = (props: CompProps) => 
   const name = props.match.params.name
   return ...;
;

【讨论】:

是的,你是对的,我删除了它。我也将其标记为已解决。无论如何谢谢

以上是关于路由器道具和自定义道具与打字稿反应路由器dom用于功能组件的主要内容,如果未能解决你的问题,请参考以下文章

使用 RouteComponentProps 和自定义道具反应路由

如何在带有打字稿的反应功能组件中定义自定义道具?

用打字稿扩展反应风格道具

从字符串 => 类型的映射推断反应道具类型时修复打字稿警告

打字稿反应组件中的反应/道具类型eslint错误

反应/打字稿:参数“道具”隐含了“任何”类型错误