用TypeScript编写,使用withRouter和Redux connect等多个HOC 的单个组件

QiaoranC 2019-09-06

定义组件propsTypes

首先定义 mapStateToProps与mapDispatchToProps

import Types from "MyTypes";
const mapStateToProps = (state: Types.RootState) => ({
    data: state.article.data,
    total: state.article.data.count
});

const mapDispatchToProps = (dispatch: Dispatch) =>
    bindActionCreators(
        {
            fetchData: (parmas: object) =>
                fetchListData({
                    ...parmas,
                    all: "all"
                }),
            fetchSingleArt: (params: object) => fetchListData({ ...params }),
            fetchTags: (params: object) => setTags({ ...params })
        },
        dispatch
    );

注:这里 Types.RootState 是我自己封装的state类型,可以根据自己实际使用编写。我自己使用了typesafe-actions,从reducers里得到了state的类型。

import { StateType, ActionType } from "typesafe-actions";
declare module "MyTypes" {
    export type RootState = StateType<
        ReturnType<typeof import("../reducers/index").default>
    >;
}

接下来定义组件的propsTypes,因为还使用了withRouter,所以要把router的属性也含进去。

import { withRouter, RouteComponentProps } from "react-router-dom";
type PropsTypes = RouteComponentProps &
    ReturnType<typeof mapDispatchProps> &
    ReturnType<typeof mapStateProps>&
    {
        //这里可以放你的组件自定义属性
    }
  class Demo<PropsTypes,StateProps>{
    ....
    }

StateProps可以根据自己情况设置,此外如果属性很多觉得写type很麻烦,我在网上看到一个很有趣的写法,分享一下

const state = {
    total: 0,
    pageSize: 10,
    page: 1,
    tableLoading: false,
    delModelVisible: false,
    currentRecord: { id: "" }
};
class Article extends React.Component<Props, typeof state> {
    state = state;
}

这样可以把state赋值和定义类型合成一步,亲测有用。

包装高阶组件

之前不用ts,一般是下面这种写法。

const enhance = compose(
    withRouter,
    connect(
        mapStateProps,
        mapDispatchProps
    )
);
export default enhance(Article);

使用ts我发现直接这么写不行,看来看去好像是compose的问题,ts中直接使用compose会有问题,你需要自己创建一个简单的修复版,这里我没使用,网上的方式在这里:How to use HOC with redux compose and Typescript

我直接套着写:

const WrappedSearchConditions = withRouter(
    connect(
        mapStateProps,
        mapDispatchProps
    )(SearchConditions)
);
export default WrappedSearchConditions;

注意:我当时使用了antDesign的form,所以等于又套了层高阶组件,直接用也会报错,大概就是你的form包过的组件,与你实际传给他的props不匹配。这里需要加上组件的propsTypes作为泛型。

const SearchConditions = Form.create<PropsTypes>({ name: "search_conditions" })(
    SearchComponent
);

参考

相关推荐