【问题标题】:router props and custom props with typescript react router dom for functional components路由器道具和自定义道具与打字稿反应路由器dom用于功能组件
【发布时间】: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 会向我抛出错误。 将自定义道具和路由器道具传递给组件的最佳做法是什么?

这是错误的屏幕截图

【问题讨论】:

    标签: javascript reactjs typescript react-router-dom


    【解决方案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 ...;
    };
    

    【讨论】:

    • 是的,你是对的,我删除了它。我也将其标记为已解决。无论如何谢谢
    猜你喜欢
    • 1970-01-01
    • 2019-08-15
    • 2021-05-24
    • 2019-01-02
    • 2020-04-05
    • 1970-01-01
    • 2017-11-08
    • 2019-10-05
    • 2023-01-03
    相关资源
    最近更新 更多