我只是尝试将我的React应用升级到
react-router - 4.0.19 to 4.0.20
反应 - 16.0.30至16.0.34
typescript- version“2.7.0-insiders.20180108”
在我的应用程序中,无论我在哪里使用'withRouter',我现在都会收到神秘的Typescript错误。我甚至用'any'替换了所有界面道具,试图让它起作用。
import * as React from 'react';
import { Switch, Route, withRouter} from 'react-router-dom';
import { Login } from './Login';
import { connect } from 'react-redux';
import { RootAction, RootState } from './_redux';
class MainForm extends React.Component<any> {
constructor(props: any) {
super(props);
}
render() {
return (
<Switch>
<Route exact={true} path="/" component={Login}/>
<Route path="/accounts" component={AccountsView}/>
</Switch>
);
}
}
const mapStateToProps = (state: RootState) => ({
state
});
export const Main = withRouter(connect(mapStateToProps)(MainForm);
错误TS2345:类型'ComponentClass&gt;的参数&安培; { WrappedComponent:ComponentType; }'不可分配给 'ComponentType&gt;'类型的参数。类型 “ComponentClass&GT; &安培; {WrappedComponent: COMPONENTTYPE; }'不能分配给类型 'StatelessComponent&GT;'。 输入'ComponentClass&gt; &安培; {WrappedComponent:ComponentType; }'不提供签名匹配'(道具: RouteComponentProps&amp; {children?:ReactNode; ,上下文?:任何): ReactElement |空”。
如果我将最后一行转换为:
export const Main = connect(mapStateToProps)(MainForm);
我没有错误。在这里非常沮丧。 感谢
编辑,我改为
export const Main = connect(mapStateToProps)(withRouter(MainForm));
像Mayank Shukla建议的那样。但现在得到错误:
错误TS2345:类型'ComponentClass&gt;'的参数是 不能分配给'ComponentType&lt; {state:RootState; }&amp; DispatchProp&GT;”。输入'ComponentClass&gt;'是 不能分配给'StatelessComponent&lt; {state:RootState; }&amp; DispatchProp&GT;”。 输入'ComponentClass&gt;'不提供签名匹配'(props:{state:RootState;}&amp; DispatchProp&amp; { 孩子?:ReactNode; },context?:any):ReactElement |空”。
答案 0 :(得分:33)
我刚刚升级到TypeScript 2.6并遇到了同样的问题。
我设法使用RouteComponentProps
解决了这个问题。
对于网址http://localhost:8080/your-component/abc
和路线
<Route component={YourComponent} path="/your-component/:param1?" />
组件应如下所示:
import * as React from 'react'
import { withRouter } from 'react-router-dom';
import {RouteComponentProps} from "react-router";
// Type whatever you expect in 'this.props.match.params.*'
type PathParamsType = {
param1: string,
}
// Your component own properties
type PropsType = RouteComponentProps<PathParamsType> & {
someString: string,
}
class YourComponent extends React.Component<PropsType> {
render() {
console.log(this.props); // Prints all props including routing-related
console.log(this.props.match.params.param1); // Prints 'abc'
console.log(typeof this.props.match.params.param1 === 'string'); // prints 'true'
return <div>...</div>;
}
}
export default withRouter(YourComponent);
答案 1 :(得分:12)
我必须这样解决:
import * as React from 'react';
import { RouteComponentProps, withRouter } from 'react-router-dom';
interface IProps extends RouteComponentProps<any> {
title: string;
}
class MyComp extends React.Component<IProps> {
public render(){
return (
<h1>{this.props.title}</h1>
)
}
}
export default withRouter<IProps>(MyComp);
答案 2 :(得分:2)
这是我通常构造输入的React组件的方式:
// These props are provided when creating the component
interface OwnProps {
// ...
}
// These props are provided via connecting the component to the store
interface StateProps {
// ...
}
// These props are provided by the router
interface PathProps {
// ...
}
class Component extends React.Component<OwnProps & StateProps & RouteComponentProps<PathProps>> {
// ...
}
const mapStateToProps = (state: State, props: OwnProps): StateProps => ({
// ...
});
export default withRouter(
connect(mapStateToProps)(Component)
);
答案 3 :(得分:1)
使用装饰器的另一种解决方案
import { withRouter, RouteComponentProps } from "react-router";
// inform we match url /:id
interface IMatchParams {
id: string;
}
// Note we use Partial<RouteComponentProps> to make all RouteComponentProps as optional for high order component
interface IComponentProps extends Partial<RouteComponentProps<IMatchParams>> {
myPersonalProp: string;
}
@withRouter
export default class MyClass extends React.Component<IComponentProps>{
public componentDidMount(){
console.log(this.props.match.params.id);
}
}
答案 4 :(得分:0)
类型脚本应用程序的工作语法变体是:
import * as React from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
class MyComponentName extends React.Component<any, any> {
constructor(props: any) {
super(props);
}
}
export default withRouter(
connect(
mapStateToProps
)(MyComponentName) as any
);
答案 5 :(得分:0)
这是我使用的功能性反应方法
import { RouteComponentProps } from "react-router";
interface Props extends RouteComponentProps {
thing: Thing | false;
onAction?: () => void;
}
export default withRouter(({ thing, onAction, history }: Props) => {
答案 6 :(得分:0)
我在TypeScript 3.6的一个非常相似/相同的问题中苦苦挣扎,无法在线找到解决方案,因此在这里我将分享自己的解决方案。我希望它可以帮助使用更复杂的应用程序的人。
javax.sound.sampled
一些注意事项:
答案 7 :(得分:0)
我遇到了这个问题,最接近我的问题的答案是这个线程。但是,我不得不将建议略微更改为以下内容。分享以防万一...
import { RouteComponentProps, withRouter } from 'react-router';
import * as React from 'react';
export interface MyComponentProps extends RouteComponentProps<any> {
propA: String;
propB: Number;
}
function MyComponent(props: MyComponentProps) {
return (
<div>
<div>{props.propA} - {props.propB}</div>
<button onClick={() => props.history.push('/some-other-page')}>Go</button>
</div>
)
}
export default withRouter(MyComponent);
答案 8 :(得分:0)
为了仍然允许在您的组件上使用自定义参数,您必须将 props 接口提供给 withRouter
。
此外,withRouter
要求您指定正在使用的组件类型(即 FunctionComponent / Component)。
另请注意,withRouter
将与道具一起提供 staticContext
。这应该从集合中删除。在将它们传递给被包装的组件之前,请使用 props,否则,您将收到此错误(除非您专门将组件接口为接受 staticContext
)。
index.js:1 Warning: React does not recognize the 'staticContext' prop on a DOM element...
对于函数组件,以下是如何正确键入 withRouter
包装器的示例:
对于类组件,以下是如何正确键入 withRouter
包装器的示例。
import React, { FunctionComponent } from 'react';
import { RouteComponentProps, withRouter } from 'react-router-dom';
interface MyCompProps extends RouteComponentProps<any> {
title: string;
}
const MyComp: FunctionComponent<MyCompProps> = ({ title }) => (
<h1>{ title }</h1>
);
export default withRouter<MyCompProps, Component<MyCompProps>>(({ staticContext, ...props }) => MyComp(props));
对于类组件,以下是如何正确键入 withRouter
包装器的示例。
import React, { Component } from 'react';
import { RouteComponentProps, withRouter } from 'react-router-dom';
interface MyCompProps extends RouteComponentProps<any> {
title: string;
}
class MyComp extends Component<MyCompProps> {
public render(){
return (
<h1>{this.props.title}</h1>
)
}
}
export default withRouter<MyCompProps, Component<MyCompProps>>(({ staticContext, ...props }) => MyComp(props));
答案 9 :(得分:-1)
如果键入“any”有问题,您可以使用这样的技巧。它对我有用。
import { withRouter, RouteComponentProps } from 'react-router-dom';
type ComponentProps = RouteComponentProps;
const Component: React.FC = () => {
return <div>This is component</div>
}
export default withRouter(Component)