javascript - 如何在 React-Redux 和 Typescript 中正确使用 'connect'

标签 javascript reactjs typescript redux react-redux

我在应用程序中使用 typescript ,但发现react-redux存在一些问题。 “connect”方法报告了一个问题,但我对此一无所知,因为我是 typescript 和 redux 的菜鸟。我应该做什么或者我的代码中的哪里应该修改?非常感谢

使用 <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ef9b969f8a9c8c9d869f9bafdcc1dc" rel="noreferrer noopener nofollow">[email protected]</a> 构建的应用程序, <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="84f6e1e5e7f0c4b5b2aabcaab1" rel="noreferrer noopener nofollow">[email protected]</a> , <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="82f0e7e3e1f6aff0e7e6f7fac2b5acb3acb2" rel="noreferrer noopener nofollow">[email protected]</a> .

// article
interface IArticle {
  title: string,
  author: string
}

// state
interface MyState {
  list: [],
  article: IArticle
}

// stateMapToProps
interface MyStateProps {
  article: IArticle
}

// router match
interface MatchParams {
  id: string
}

// own props
interface MyOwnProps extends RouteComponentProps < MatchParams > {
  article: IArticle,
  dispatch: (o: object) => {}
}

class ArticleContainer extends Component < MyOwnProps, {} > {
  constructor(props: MyOwnProps) {
    super(props);
  }

  componentDidMount() {
    const {
      dispatch
    } = this.props;
    const id = this.props.match.params.id
    dispatch(fetchArticle(id))
  }

  render() {
    const {
      article
    } = this.props;
    return ( <
      Article article = {
        article
      } > < /Article>
    )
  }
}

const mapStateToProps = (state: MyState): MyStateProps => {
  return {
    article: state.article
  }
}

export default connect < MyStateProps, {}, {
  article: IArticle
} > (
  mapStateToProps
)(ArticleContainer)

这是异步操作的代码 fetchArticle

function fetchArticle(id: string) {
  return function(dispatch: (action: AnyAction) => {}): Promise<void> {
    dispatch(getArticle(id))

    return axios.get(`/article/${id}`)
      .then(res => {
        dispatch(getArticleSuccess(res.data))
      })
  }
}

错误发生在 export行和消息如下:

Argument of type '(state: MyState) => MyStateProps' is not assignable to parameter of type 'MapStateToPropsParam'. Type '(state: MyState) => MyStateProps' is not assignable to type 'MapStateToPropsFactory'. Types of parameters 'state' and 'initialState' are incompatible. Type '{}' is missing the following properties from type 'MyState': list, articlets(2345)

最佳答案

编译代码的最少步骤:

  1. MyOwnProps 应该是

    import { AnyAction } from 'redux';
    
    interface AppThunkAction<TAction> {
        (dispatch: (action: TAction) => void, getState: () => MyState): any;
    }
    
    // As you're going to dispatch thunk actions, dispatch should be overloaded
    interface Dispatch<TAction> {
        (action: AppThunkAction<TAction>): any
        (action: TAction): TAction
    }
    
    // own props
    interface MyOwnProps extends RouteComponentProps<MatchParams> {
        article: IArticle,
        dispatch: Dispatch<AnyAction>
    }
    
  2. 如果您想为 connect 函数提供类型,请将 MyState 添加为最后一个类型,如下所示

    export default connect <MyStateProps, {}, {
            article: IArticle
        }, MyState >(
            mapStateToProps
    )(ArticleContainer)
    

    或者您可以允许编译器自行推断类型,这是首选

    export default connect(
        mapStateToProps
    )(ArticleContainer)
    

工作结果

import { Component } from 'react';
import { RouteComponentProps } from 'react-router-dom';
import { connect, ResolveThunks } from 'react-redux';
import { AnyAction } from 'redux';
import axios from 'axios';

// article
interface IArticle {
    title: string,
    author: string
}

// state
interface MyState {
    list: [],
    article: IArticle
}

// stateMapToProps
interface MyStateProps {
    article: IArticle
}

// router match
interface MatchParams {
    id: string
}

export interface AppThunkAction<TAction> {
    (dispatch: (action: TAction) => void, getState: () => MyState): any;
}

interface Dispatch<TAction> {
    (action: AppThunkAction<TAction>): any
    (action: TAction): TAction
}

// own props
interface MyOwnProps extends RouteComponentProps<MatchParams> {
    article: IArticle,
    dispatch: Dispatch<AnyAction>
}

function getArticle(id: string) {
    return {
        type: 'GET_ARTICLE',
        id
    }
}

function getArticleSuccess(i: any) {
    return {
        type: 'SET_ARTICLE',
        i
    }
}



const fetchArticle = (id: string): AppThunkAction<AnyAction> =>
    (dispatch, getState) => {
        dispatch(getArticle(id))

        return axios.get(`/article/${id}`)
            .then(res => {
                dispatch(getArticleSuccess(res.data))
            })
    }

class ArticleContainer extends Component<MyOwnProps, {}> {
    constructor(props: MyOwnProps) {
        super(props);
    }

    componentDidMount() {
        const {
            dispatch
        } = this.props;
        const id = this.props.match.params.id
        dispatch(fetchArticle(id))
    }

    render() {
        const {
            article
        } = this.props;
        return (<div>article: {article}</div>
          )
        }
      }

const mapStateToProps = (state: MyState): MyStateProps => {
  return {
                article: state.article
          }
        }

export default connect(
            mapStateToProps
)(ArticleContainer)

关于javascript - 如何在 React-Redux 和 Typescript 中正确使用 'connect',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56963211/

相关文章:

javascript - 更新到 Chrome v65 并开始收到此错误 : Expected onClick listener to be a function, 而不是收到类型字符串

javascript - 当 CSS 中的下拉菜单可见时,如何删除父组件中的按钮?

angular - 未知的编译器选项 'noStrictGenericChecks'

javascript - Styled-components React HTML 元素工厂

javascript - YouTube 自动播放并静音

javascript - HTML, JS 如何在悬停时播放/停止视频

javascript - D3js 工具提示未正确生成

javascript - 使用 vanilla javascript 隐藏包含特定文本的标签

javascript - 我的 cron 作业始终包含相同的标记值

angularjs - angular_1.default.module 未捕获类型错误 : Cannot read property 'module' of undefined