响应路由器错误,实现匹配接口

iJa*_*ava 1 typescript reactjs

我的问题是,在实现反应路由器后,我不明白如何重用组件。!(听起来很愚蠢..)

路线.tsx:

import * as React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import { Redirect } from "react-router-dom";
import { Subscription } from "./components/Subscription";
import { Billing } from "./components/Billing";
import { Layout } from "./components/Layout";
import { NavigationMenu } from "./components/NavigationMenu";

export const routes =
    <Router>
        <Layout>
            <NavigationMenu />

            <Redirect from="/" to="/Subscription" />
            <Route exact path="/Subscription" component={Subscription} />
            <Route exact path="/Billing" component={Billing} />
        </Layout>
    </Router>;
Run Code Online (Sandbox Code Playgroud)

订阅.tsx

import * as React from "react";
import { CustomerSelection } from "./CustomerSelection";
import { ProfileSelection } from "./ProfileSelection";
import { OrderSubmission } from "./OrderSubmission";
import { FileDownload } from "./FileDownload";
import { VoomConfig } from "../voomconfig";
import { RouteComponentProps } from "react-router-dom";
import { SubscriptionLines } from "./SubscriptionLines";

export class Subscription extends React.Component<RouteComponentProps<{}>, ICustomerState> {
    constructor() {
        super();

        const config: IAppSettings = require("Config");

    ...
    }
}
Run Code Online (Sandbox Code Playgroud)

在实现路由器<Subscription />组件之前 使用RouteProps而不是RouteComponentPros..

现在,路由似乎正在运行,但如果我需要,re-use/test my Subscription component我正在接收

Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<Subscription> & Readonly<{ children?: ReactNode; }...'.
  Type '{}' is not assignable to type 'Readonly<RouteComponentProps<{}>>'.
    Property 'match' is missing in type '{}'.
Run Code Online (Sandbox Code Playgroud)

我明白我需要实现该接口并在重用时设置道具 <Subscription ....props />

但是我用谷歌搜索了很多,我无法解决这个问题..:/项目的所有依赖项。

{
  "name": "test_name",
  "private": true,
  "version": "0.0.0",
  "devDependencies": {
    "@types/enzyme": "^3.1.9",
    "@types/history": "4.6.0",
    "@types/jest": "^22.2.0",
    "@types/react": "15.0.35",
    "@types/react-dom": "15.5.1",
    "@types/react-hot-loader": "3.0.3",
    "@types/react-router": "4.0.12",
    "@types/react-router-dom": "4.0.5",
    "@types/webpack-env": "1.13.0",
    "aspnet-webpack": "^2.0.1",
    "aspnet-webpack-react": "^3.0.0",
    "awesome-typescript-loader": "3.2.1",
    "bootstrap": "3.3.7",
    "css-loader": "0.28.4",
    "enzyme": "^3.3.0",
    "enzyme-adapter-react-15": "^1.0.5",
    "event-source-polyfill": "0.0.9",
    "extract-text-webpack-plugin": "2.1.2",
    "file-loader": "0.11.2",
    "isomorphic-fetch": "2.2.1",
    "jest": "^22.4.2",
    "jest-mock-axios": "^1.0.21",
    "jquery": "3.2.1",
    "json-loader": "0.5.4",
    "react": "15.6.1",
    "react-dom": "15.6.1",
    "react-hot-loader": "3.0.0-beta.7",
    "react-router-dom": "4.1.1",
    "react-test-renderer": "^15.6.2",
    "react-transition-group": "^2.2.1",
    "style-loader": "0.18.2",
    "typescript": "2.4.1",
    "url-loader": "0.5.9",
    "webpack": "2.5.1",
    "webpack-hot-middleware": "2.18.2"
  },
  "dependencies": {
    "axios": "^0.17.1",
    "babel-polyfill": "^6.26.0",
    "classnames": "^2.2.5",
    "font-awesome": "^4.7.0",
    "primereact": "^1.4.1",
    "tslint": "^5.9.1",
    "tslint-react": "^3.4.0"
  },
  "scripts": {
    "test": "jest",
    "test:watch": "jest --watch",
    "test:coverage": "jest --coverage",
    "build": "./node_modules/.bin/webpack",
    "debug": "node --debug-brk --inspect ./node_modules/jest/bin/jest -i"
  },
  "jest": {
    "setupFiles": [
      "<rootDir>/test-shim.js",
      "<rootDir>/test-setup.js"
    ],
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js"
    ],
    "moduleNameMapper": {
      "^Config$": "<rootDir>/appsettings.Development.json"
    },
    "transform": {
      "^.+\\.(ts|tsx)$": "<rootDir>/test-preprocessor.js"
    },
    "testMatch": [
      "**/__tests__/*.(ts|tsx|js)"
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

*** 如果我的解释有误,或者有什么遗漏,请告诉我。!非常感谢提前。!

编辑:

interface RouteComponentProps<P> {
  match: match<P>;
  location: H.Location;
  history: H.History;
  staticContext?: any;
}
Run Code Online (Sandbox Code Playgroud)

Tha*_*ran 5

您应该在使用它时尝试了解基本的周围Typescript和 React Typescript

class Subscription extends React.Component<RouteComponentProps<{}>, ICustomerState> {...}
Run Code Online (Sandbox Code Playgroud)

使用该组件声明,您告诉 Typescript 该Subscription组件具有泛型RouteComponentProps作为 prop 类型。我假设您使用的是版本react-router3,RouteComponentProps此版本声明如下:

interface RouteComponentProps<P, R> {
    location: Location;
    params: P & R;
    route: PlainRoute;
    router: InjectedRouter;
    routes: PlainRoute[];
    routeParams: R;
} 
Run Code Online (Sandbox Code Playgroud)

有了这个声明,location,params等等 都是必需的道具,因此 Typescript 会要求你在Subscription任何你想使用它的地方为你的组件提供这些道具。

当您尝试在不提供这些道具的情况下使用此组件时,会发生您收到的错误,例如:

<Subscription />

这是Typescript.

如果您想重用Subscription组件内部的逻辑或表示,请为其创建另一个组件,不要使用RouteComponentProps该组件的 props。然后您可以在Subscription组件(路由组件)内使用它。

  • 是的,一旦你将 `RouteComponentProps` 声明为它的 props,你就不能使用 `&lt;Subscription /&gt;`。你总是可以自己声明你的组件 props,但是,它可能与 `react-router``Route.component` 属性类型不兼容。我相信 react-router `Route` 需要传递给它的 props `component` 的组件的 props 类型等于或扩展自 `RouteComponentProps`。解决它的更好方法是将可重用部分包装到另一个组件中。 (2认同)