用TypeScript編寫,使用withRouter和Redux connect等多個HOC 的單個組件

定義組件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
);

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章