在 typescript 中使用 react-redux connect

新手上路,请多包涵

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

应用程序.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;

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

容器/测试页/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)

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

容器/测试页/测试页.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>
    );
  }
}

错误信息:

 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'.

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

  • 为什么当我定义它们时,我的属性不存在于 this.props 上?
  • connect 中到底什么是不可分配的?

原文由 Simon 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 441
2 个回答

我注意到几件事:

  1. 据我在示例中看到的以及在 TypeScript 中使用 props 时,您对 React.Component 调用需要指定 Props 365e6a381 之类的参数所以:
 export default class TestPage extends React.Component<Test.Props, Test.State>{

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

}

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

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

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

}

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

  1. 你的 mapStateToProps 函数看起来不太正确。 mapStateToProps takes two arguments, state (referencing your Redux store ) and ownProps as an optional second argument, which refers to props 从父代传下来的。所以 mapStateToProps 应该是这样的:
 function mapStateToProps(state: any, ownProps: { label: string }) {

    return {
        label: ownProps.label
    };
}

这是我对为什么 connect 抛出错误的猜测 - 它只是一个你断言 Redux 应该如何处理组合的地方 props 来自 storeprops 来自父母。让我知道这是否有效。

原文由 Parker Ziegler 发布,翻译遵循 CC BY-SA 3.0 许可协议

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

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

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

原文由 Kacper Wiszczuk 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题