ReactJS TS,Property&#39;匹配&#39;类型&#39; Readonly&lt; {children?:ReactNode}&gt;上不存在&安培;只读<myprops>&#39;

时间:2018-05-01 13:05:21

标签: reactjs typescript

我正在尝试键入组件的道具并同时使用URL参数。我收到以下错误:

  

属性&#39;匹配&#39;在类型上不存在   &#39;只读&LT; {小孩:ReactNode?}&GT; &安培;只读&#39;

以下是我的一些代码:

import Api from '../../api/Api';

interface MyProps {
    api: Api
}

interface MyState {
    someString: string,
    loading: boolean
}

export class MyComponent extends React.Component<MyProps, MyState> {

    constructor(props: MyProps) {
        super(props);
        this.state = {
            someString: this.props.match.params.someString,//<-- Error is here on this line
            loading: true
        }
    }

    componentDidMount() {
        this.props.api.getSomeInfo(this.state.someString, this.callback)
    }

    callback() {
        let interval = setInterval(function () {
            this.setState({loading: false});
            clearInterval(interval)
        }, 3000);
    }

    render() {
        return (
            <div>
                <p>{this.someString}</p>
            </div>
        );
    }
}

正如你所看到的,我想做的就是:

1-转到:

  

http://localhost:8080/someStrings/:someString

2-在我的组件的构造函数中获取:someString的值并以状态存储

3-在我的状态下使用someString的值,可以将它作为参数传递给我的API模块来做东西

4-在API中执行回调时,我删除了加载动画

我的问题基本上是,如何声明我的MyProps能够实现这一目标?

10 个答案:

答案 0 :(得分:5)

这是类型定义中的一个未解决的问题。 https://github.com/DefinitelyTyped/DefinitelyTyped/issues/17355

解决方法

import { RouteProps } from 'react-router';
import React from 'react';

interface MyProps {
    api: Api
}

interface MyState {
    someString: string,
    loading: boolean
}

class MyComponent extends React.Component<Props & RouteProps, State> // Pay attention here.
{
  // your code...
}

参考:https://github.com/DefinitelyTyped/DefinitelyTyped/issues/17355#issuecomment-336022780

答案 1 :(得分:1)

尝试将 RouteComponentProps 接口添加到道具中。更改:

export class MyComponent extends React.Component<MyProps, MyState> {

export class MyComponent extends React.Component<MyProps & RouteComponentProps, MyState> {

答案 2 :(得分:1)

我遇到了类似的问题,发现最小的类型破坏解决方案是将参数本地转换为任意参数。

someString: (this.props.match.params as any).someString

答案 3 :(得分:1)

这就是我解决的方式

import {RouteComponentProps} from 'react-router';
interface IMyProps {}

interface IReactRouterParams {
  roomName: string;
  username: string;
}
export class MyComponent extends React.Component<
  IMyProps & RouteComponentProps<IReactRouterParams> {
 
  constructor(props: any) {
    super(props);
    //everything works here
    const {roomName, username} = this.props.match.params;
  }
}

答案 4 :(得分:0)

我有完全相同的事情。我不明白,因为当我在Chrome中调试时,我可以看到参数在那里,所以我真的很困惑。

enter image description here

但VSCode和Yarn坚持说它不在那里:

enter image description here

答案 5 :(得分:0)

我遇到了类似的问题,这是由于 App.test.jsx 文件造成的。那里已经有一个我完全忘记的测试用例(下面的代码),并且在该测试用例场景中没有使用任何道具。

当我将道具引入测试用例时,它就起作用了。因此,在自然界,测试肯定是在朝正确的方向发展,因为它试图使用不存在的道具。但是用我的默认道具更新了测试用例之后,它就可以工作了。

希望这会有所帮助。

it('renders without crashing', () => { const div = document.createElement('div'); ReactDOM.render(<App **propName1={propwasnotinthetest} propName2={propwasnotinthetest}**/>, div); ReactDOM.unmountComponentAtNode(div); });

答案 6 :(得分:0)

RouteComponentProps应该有助于打字稿

import { RouteComponentProps } from 'react-router';

export class Edit extends React.Component<MyProps & RouteComponentProps, MyState> {
  constructor(props: MyProps & RouteComponentProps) {
    super(props);

    ...
}
...
(this.props.match.params as any).someString

答案 7 :(得分:0)

这是我处理match问题的脚本,我相信您可以从这里借用一些东西。

class MyComponent extends React.Component<Props, State> {
  private params: any;

  constructor(props: any) {
    super(props);
    this.state = {
      paramId: null
    };
  }

  componentDidMount = () => {
    this.getParams();
  };

  getParams = () => {
    this.params = this.props;

    this.setState({
      paramId: this.params.match.params.id
    });
  };

  render() {
    const { paramId } = this.state;

    return (
      <React.Fragment></React.Fragment>
    );
  }
}

export default MyComponent;

答案 8 :(得分:0)

    import * as React from 'react';
    import { RouteComponentProps } from 'react-router';

    interface RouteComponetPath {
        path?: string
    }

    interface ArticleContainerProps {
        another: number
    }

    interface ArticleContainerState {
        path?: string;
    }

    class ArticleContainer extends React.Component<ArticleContainerProps | RouteComponentProps<RouteComponetPath>, ArticleContainerState> {
        constructor(props: ArticleContainerProps | RouteComponentProps<RouteComponetPath>) {
            super(props);
            this.state = {
                path: (this.props as RouteComponentProps<RouteComponetPath>).match.params.path
            };
        }

        componentDidMount() {
            console.log("mount! Path is: ", this.state.path);
        }

        render() {
            return (
                <h1>This is a page with path {this.state.path} </h1>
            )
        }
    }

    export default ArticleContainer;

根据TS文档https://www.typescriptlang.org/docs/handbook/advanced-types.html#union-types

,您实际上可以使用一个接口来处理路径并使用Union类型和Type Gueard,这实际上很有意义。

因此,没有任何黑客攻击,并且保持强类型(不使用任何地方)。

现在我看不到有任何理由同时通过路径和其他类型的参数,但是您知道...只是为了证明可以做到。

答案 9 :(得分:0)

或者因为您使用的是DiscoverPage而没有在 MyProps 界面中添加 match