typescript - 使用“withRouter”和 Typescript 时的类型问题
问题描述
我正在尝试在 React+Typescript 中获得一些更深入的知识和实践,并且在使用withRouter
from时遇到了这个打字错误react-router-dom
。
我的代码片段非常简单,我尝试找出有同样问题的人,其中一些答案指出升级时出错(但它们是从 2016 年开始的,所以......)其中一些正在使用一个connect()
我没有使用的声明(这导致了一个问题,“我做错了是因为没有使用它吗?”)。我看到其中一些建议还涉及将 Props 映射到 State,直到现在我还没有做过(也没有见过)。我希望有人对我缺少什么以及我应该看什么有一些建议。
代码是:
import React from "react";
import { withRouter } from "react-router-dom";
interface ISection {
id: number;
title: string;
imageUrl: string;
size: string;
}
class MenuItem extends React.Component<ISection> {
render() {
return (
<div className={`${this.props.size} menu-item`}>
<div
className="background-image"
style={{ backgroundImage: `url(${this.props.imageUrl})` }}
/>
<div className="content">
<h1 className="title">{this.props.title}</h1>
<span className="subtitle">some subtitle</span>
</div>
</div>
);
}
}
export default withRouter(MenuItem);
我期望从这里顺利工作(我不得不说我首先尝试了一个功能组件,因为我没有任何状态,但是我看到的所有解决方案都涉及一个类组件,所以我把它移到它里面),但我MenuItem
在最后一行收到以下错误:
Argument of type 'typeof MenuItem' is not assignable to parameter of type 'ComponentClass<RouteComponentProps<any, StaticContext, any>, any> | FunctionComponent<RouteComponentProps<any, StaticContext, any>> | (FunctionComponent<RouteComponentProps<any, StaticContext, any>> & ComponentClass<...>) | (ComponentClass<...> & FunctionComponent<...>)'.
Type 'typeof MenuItem' is not assignable to type 'ComponentClass<RouteComponentProps<any, StaticContext, any>, any>'.
Types of parameters 'props' and 'props' are incompatible.
Type 'RouteComponentProps<any, StaticContext, any>' is missing the following properties from type 'Readonly<ISection>': id, title, imageUrl, sizets(2345)
我的问题是:
为什么它说“type 'typeof MenuItem'”?不应该只说'MenuItem'的类型而不是获取类型的函数吗?
withRouter 是否有必要与类组件一起使用,或者它也适用于功能组件?
我需要
connect()
做些什么,或者将 Props 映射到 State 上吗?如果是这样,为什么?最后,我该如何解决这个问题?
解决方案
在文档中,无论何时渲染,withRouter
都会将 updated match
、location
和history
props 传递给包装的组件。
所以MenuItem
组件应该有道具来接收它们。目前,MenuItem
组件的 props 类型ISection
不包括路由器 props。
添加路由器道具的最简单方法是ISection
与RouteComponentProps
.
import { withRouter, RouteComponentProps } from "react-router-dom";
// ...
class MenuItem extends React.Component<ISection & RouteComponentProps> {
完整代码是
import * as React from 'react';
import { withRouter, RouteComponentProps } from "react-router-dom";
interface ISection {
id: number;
title: string;
imageUrl: string;
size: string;
}
class MenuItem extends React.Component<ISection & RouteComponentProps> {
render() {
return (
<div className={`${this.props.size} menu-item`}>
<div
className="background-image"
style={{ backgroundImage: `url(${this.props.imageUrl})` }}
/>
<div className="content">
<h1 className="title">{this.props.title}</h1>
<span className="subtitle">some subtitle</span>
</div>
</div>
);
}
}
export default withRouter(MenuItem);
并回答您的问题
为什么它说“type 'typeof MenuItem'”?不应该只说'MenuItem'的类型而不是获取类型的函数吗?
错误是由类型不兼容引起的。
MenuItem
是类,不是类型。要获取类型,MenuItem
您应该使用typeof MenuItem
. 类型也是如此typeof MenuItem
。编译器正确地说,“类型typeof MenuItem
”。withRouter 是否有必要与类组件一起使用,或者它也适用于功能组件?
允许与类组件和功能组件一起使用。
如果实现为功能性组件,这就是您的组件的外观
const Cmp1: React.FunctionComponent<ISection & RouteComponentProps> = (props) => { return ( <div className={`${props.size} menu-item`}> <div className="background-image" style={{ backgroundImage: `url(${props.imageUrl})` }} /> <div className="content"> <h1 className="title">{props.title}</h1> <span className="subtitle">some subtitle</span> </div> </div> ); } const WrappedCmp = withRouter(Cmp1);
我需要
connect()
做些什么,或者将 Props 映射到 State 上吗?如果是这样,为什么?不,这不是严格的要求。
connect
是 Redux 的一部分,所以如果你使用 Redux,你可以连接。这是有关如何使用with的文档。但同样,它不是必需的。withRouter
connect
最后,我该如何解决这个问题?
已经回答了。往上看 :-)
推荐阅读
- javascript - 在 html 中添加火车游戏需要一点帮助
- heroku - 带有容器堆栈和 ENTRYPOINT 指令的 Heroku 继续使用“/bin/sh -c”运行
- python-3.x - 如何自定义匹配大熊猫数据框?
- c# - 为 2 个不同的外部应用程序创建 2 组 .Net C# 插件,这些应用程序除了命名空间外具有相同的 API
- swift - 在 Swift 中,什么是优雅的方式,或者是假的“类型双关语”
- java - 如何将变量从一种方法传递到另一种方法?
- sql - 获取字符串中的最高值数字
- javascript - 我不希望我的表单在提交后刷新
- python-3.x - 无法在 Azure 函数中运行 python 代码
- swift - 在延迟创建的视图上调用 removeFromSuperview() 会实例化它吗?