typescript 在打字稿中使用 react-redux connect

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47104264/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 05:00:40  来源:igfitidea点击:

Use react-redux connect in typescript

javascriptreactjstypescriptreduxreact-redux

提问by Simon

I try to build a react app in typescript using redux and react-router-dom. I ran into typing issues when I added redux to my app. Thus I created the following minimal example with only one page test-page:

我尝试使用 redux 和 react-router-dom 在打字稿中构建一个 react 应用程序。当我将 redux 添加到我的应用程序时,我遇到了输入问题。因此,我创建了以下最小示例,其中只有一页test-page

App.jsx

应用程序.jsx

import * as React from 'react';
import { Route, Redirect } from 'react-router-dom'
import Test from './containers/test-page'
import './App.css';

class App extends React.Component {
  render() {
    return (
      <div className="ui container" id="main">
        <Route exact path="/" render={() => <Redirect to="/test" />}/>
        <Route exact path="/test" component={Test} />
      </div>
    );
  }
}

export default App;

The container for the test page looks like this. It produces a typing error in the call to connect.

测试页的容器如下所示。它会在调用connect 时产生输入错误。

containers/test-page/index.tsx

容器/测试页/index.tsx

import { Dispatch } from 'redux'
import { connect } from 'react-redux'
import TestPage from './test-page'

function mapDispatchToProps(dispatch: Dispatch<any>) {
  return dispatch({ type: 'ALERT_USER' });
}

function mapStateToProps(state: any) {
  return { label: 'my test label' }
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(TestPage)

The container uses the following react component, which in production should render a page for the router. It produces two errors, see below.

容器使用以下反应组件,它在生产中应该为路由器呈现页面。它产生两个错误,见下文。

containers/test-page/test-page.tsx

容器/测试页面/测试页面.tsx

import * as React from 'react';

export namespace Test {
  export interface Props {
    alert: () => void;
    label: string;
  }

  export interface State {
  }
}

export default class TestPage extends React.Component {

  constructor(props?: Test.Props, state?: Test.State, context?: any) {
    super(props, context);
  }

  sendAlert = () => {
      this.props.alert()
  }

  render() {
    return (
      <div>
        <h1>Test</h1>
        <button onClick={this.sendAlert}>{this.props.label}</button>
      </div>
    );
  }
}

Error messages:

错误信息:

proxyConsole.js:54 ./src/containers/test-page/test-page.tsx
(20,18): error TS2339: Property 'alert' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.

proxyConsole.js:54 ./src/containers/test-page/test-page.tsx
(27,54): error TS2339: Property 'label' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.

proxyConsole.js:54 ./src/containers/test-page/index.tsx
(16,3): error TS2345: Argument of type 'typeof TestPage' is not assignable to parameter of type 'ComponentType<{ label: string; } & { type: string; }>'.
  Type 'typeof TestPage' is not assignable to type 'StatelessComponent<{ label: string; } & { type: string; }>'.
    Type 'typeof TestPage' provides no match for the signature '(props: { label: string; } & { type: string; } & { children?: ReactNode; }, context?: any): ReactElement<any> | null'.

I tried to follow different guides and looked up example implementations but could not solve these issues. I do not understand the error messages of the typescript compiler:

我尝试遵循不同的指南并查找示例实现,但无法解决这些问题。我不明白打字稿编译器的错误信息:

  • Why do my properties not exist on this.propswhen I defined them?
  • What exactly is not assignable in connect?
  • 为什么this.props我定义的属性不存在?
  • 在连接中究竟什么是不可分配的?

回答by Parker Ziegler

A couple of things I notice:

我注意到的几件事:

1) As far as I've seen in examples and when working with propsin TypeScript, your call to React.Componentneeds to specify Propsas a type argument like so:

1)据我在示例中看到以及props在 TypeScript 中使用时,您的调用React.Component需要指定Props为类型参数,如下所示:

export default class TestPage extends React.Component<Test.Props, Test.State>{

    constructor(props: Test.Props) {
        super(props);
    }

}

You can specify that your component does not accept propsor stateby passing empty interfaces i.e.:

您可以指定您的组件不接受propsstate通过传递空接口,即:

export default class TestPage extends React.Component<{}, {}>{

    // constructor becomes 'useless' at this point and is not needed
    constructor() {
        super();
    }

}

I think this explains why your call signature is not matching and why there are no properties visible on this.props- TS sees an interface of ReadOnly{}since it has no type arguments passed in.

我认为这解释了为什么您的调用签名不匹配以及为什么没有可见的属性this.props- TS 看到了一个接口,ReadOnly{}因为它没有传入的类型参数。

2) Your mapStateToPropsfunction doesn't look quite right. mapStateToPropstakes two arguments, state(referencing your Redux store) and ownPropsas an optional second argument, which refers to propspassed down from the parent. So mapStateToPropsshould look like this:

2) 你的mapStateToProps函数看起来不太对劲。mapStateToProps接受两个参数,state(引用您的 Redux store)和ownProps作为可选的第二个参数,它指的是props从父级传递下来的。所以mapStateToProps应该是这样的:

function mapStateToProps(state: any, ownProps: { label: string }) {

    return {
        label: ownProps.label
    };
}

This is my guess for why connectis throwing an error - it is simply a place where you make assertions about how Redux should handle combining propscoming from the storeand propscoming from the parent. Let me know if this works out.

这就是我为什么猜测connect是抛出一个错误-它只是在这里你做出终极版应该如何处理合并断言的地方props,从即将到来的storeprops从父到来。让我知道这是否有效。

回答by Kacper Wiszczuk

This doesn't work because connect is a generic function. This means you need to provide additional type parameters.

这不起作用,因为 connect 是一个通用函数。这意味着您需要提供额外的类型参数。

connect<StateProps, DispatchProps>({
    mapStateToProps,
    mapDispatchToProps,
})(SomeComponent);

You can find typing implementation here. Everything you need to know is there C:

您可以在此处找到打字实现。你需要知道的一切都在那里 C:

回答by Hymankobec

Working syntax variant for Type Script application is:

Type Script 应用程序的工作语法变体是:

    import * as React from 'react';
    import { connect } from 'react-redux';

    interface ComponentProps {
    // Your properties here
    }

    interface ComponentState {
    // Your properties here
    }

    interface MapStateToPropsTypes {
    // Your properties here
    }

    interface MapDispatchToPropsTypes {
    // Your properties here
    }

    class MyComponentName extends React.Component<ComponentProps, ComponentState> {
        constructor(props: ComponentProps) {
            super(props);
        }
    }

    export default connect<MapStateToPropsTypes, MapDispatchToPropsTypes>(
      mapStateToProps,
      mapDispatchToProps)
    (MyComponentName)