使用Redux的Typescript,如何使用connect而不重新声明动作定义?

时间:2017-06-23 09:04:55

标签: reactjs typescript redux react-redux

我对打字稿和redux-thunk行为感到不便。

基本上我的组件大量使用react-redux连接来绑定动作创建者,问题是,当我在组件中为这个redux动作创建接口时,我必须重新声明函数定义,因为它会丢失连接电话。

以下是示例代码:

动作创作者

import api from './api';
import { Dispatch } from 'redux';
import { IReduxAction } from 'model';

export const FETCH_ENTITY = 'location/FETCH_ENTITY';
export function fetchEntity(id: string) {
  return (dispatch: Dispatch<IReduxAction>) => {
    dispatch({type: `${FETCH_ENTITY}_REQUEST`, payload: {id}});

    return api.fetchEntity(id)
              .then((res) => {

                dispatch({ type: `${FETCH_ENTITY}_DONE`, payload: res });
                return res;
              })
              .catch((err) => {
                dispatch({type: `${FETCH_ENTITY}_FAIL`, payload: err, error: true});
                throw err;
              });
  };
}

组件

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

import {
  fetchEntity,
} from 'actions';

interface IStateProps {
  startingEntities: any[];
}

interface IDispatchProps {
  fetchEntity: (id: string) => Promise<any>; // <- this is what I'm trying to get rid of, basically whenever I change the action creator I have to change this definition everytime
}

class Dashboard extends React.Component<IStateProps & IDispatchProps, void> {

  public render() {

    return (<div>...RENDER SOMETHING...</div>);
  }

}

const mapStateToProps = (state: any, ownProps: any) => {
  const startingEntities = foo(); // not important

  return {
    startingEntities,
  };
};

const mapDispatchToProps = (dispatch: any) => {
  return bindActionCreators({
    fetchEntity
  }, dispatch);
};

export default connect<IStateProps, IDispatchProps, void>(mapStateToProps, mapDispatchToProps)(Dashboard);

无论如何都要声明这个绑定的动作创建者而不必每次都在每个文件上重新声明它?

3 个答案:

答案 0 :(得分:8)

您不需要再次定义功能类型。您可以使用save

typeof

答案 1 :(得分:1)

我对TypeScript不太熟悉(大部分刚刚为库接口完成了index.d.ts个文件)但你应该能够通过正确输入{{1来让类型系统为你完成工作并导出它以供fetchEntity使用。像

这样的东西
IDispatchProps

然后你可以导入它并使用相同的定义

//...

import { ThunkAction } from 'redux-thunk'

//...

export interface FetchEntity {
  (id: string): ThunkAction<Promise<any>, IReduxAction, any>;
}

//...

export const fetchEntity: FetchEntity = (id: string) => {
  return (dispatch: Dispatch<IReduxAction>) => {
    //...
  };
}

答案 2 :(得分:0)

我不确定你正在寻找的设计模式,但是动作创建者只是一个简单的对象,当它使用它时,reducer需要一个属性'type'。

因此,我认为处理这种情况的最佳方法是获取一个包含您将要导出的操作的专用文件,然后导入它们。关于为dispatc选择操作的逻辑将在你的组件行为中,这在我看来更好。

我希望这有助于解决您的问题:)