reactjs - Typescript și Redux connect


Încerc să conectez redux la un component folosind Typescript și mă lovesc mereu de aceeași eroare.

Argumentul de tip 'typeof BaseLayoutUnconnected' nu poate fi atribuit parametrului de tip 'Component'. Proprietatea 'setState' lipsește în tipul 'typeof BaseLayoutUnconnected'.

import * as React from 'react';
import { IBaseLayoutProps, IBaseLayoutState } from './base-layout.types';
import { ChatContainer } from '../../components';
import { connect, DispatchProp } from 'react-redux';
import { bindActionCreators, Dispatch } from 'redux';
import { RouteComponentProps } from 'react-router';
import { ChatActions } from 'app/actions';
import { RootState } from 'app/reducers';
import { omit } from 'app/utils';

export const mapStateToProps = (state: RootState, ownProps) => {
    return {
        chatItems: state.chatItems
    };
};

export const mapDispatchToProps = (dispatch: Dispatch) => ({
    actions: bindActionCreators(omit(ChatActions, 'Type'), dispatch)
});

export class BaseLayoutUnconnected extends React.Component<IBaseLayoutProps, IBaseLayoutState> {
   constructor(props) {
        super(props);
        this.state = {};
    }

    render() {
        const { actions, chatItems } = this.props;
        return <ChatContainer actions={actions} chatItems={chatItems} />;
    }
}

export const BaseLayout = connect(
    mapStateToProps,
    mapDispatchToProps
)(BaseLayoutUnconnected);

Acesta este apelat în app.tsx-ul meu prin

 <Route exact={true} path="/" component={BaseLayout} />

Iată proprietățile și starea

export interface IBaseLayoutProps {
    chatItems: RootState.ChatState;
    actions: ChatActions;
}

export interface IBaseLayoutState {}

ChatActions arată ca

import { createAction } from 'redux-actions';
import { ChatItemModel } from 'app/models';

export namespace ChatActions {
    export enum Type {
        ADD_CHAT_ITEM = 'ADD_CHAT_ITEM'
    }

    export const addChatItem = createAction<PartialPick<ChatItemModel, 'text'>>(Type.ADD_CHAT_ITEM);
}

export type ChatActions = Omit<typeof ChatActions, 'Type'>;

Răspuns #1

Aceasta este o problemă pe care am avut-o și eu când am început prima dată cu Redux și TypeScript. Există o soluție complicată. Metoda connect folosește multe generice. Voi încerca să explic cu exemplul tău.

În primul rând trebuie să împarți proprietățile BaseLayoutUnconnected-ului tău.

export interface IBaseLayoutStateProps {
    chatItems: RootState.ChatState;
}

export interface IBaseLayoutDispatchProps {
    actions: ChatActions;
}

export interface IBaseLayoutOwnProps {
    // put properties here you want to make available from the connected component
}

export type IBaseLayoutProps = IBaseLayoutOwnProps & IBaseLayoutDispatchProps & IBaseLayoutStateProps 

export interface IBaseLayoutState {}

Apoi trebuie să completezi genericele diferitelor funcții redux.

const mapStateToProps: MapStateToProps<IBaseLayoutStateProps, {}, RootState> = (state: RootState): IBaseLayoutStateProps => ({
    chatItems: state.chatItems
})

export const mapDispatchToProps: MapDispatchToPropsFunction<IBaseLayoutDispatchProps, IBaseLayoutOwnProps> = (dispatch: Dispatch, ownProps: IBaseLayoutDispatchProps): IBaseLayoutDispatchProps => ({
    actions: bindActionCreators(omit(ChatActions, 'Type'), dispatch)
});

export default connect<IBaseLayoutStateProps , IBaseLayoutDispatchProps, IBaseLayoutOwnProps , RootState>(
    mapStateToProps,
    mapDispatchToProps
)(BaseLayoutUnconnected as any)

o sursă bună, unde poți găsi toate aceste lucruri pe care le-am scris și mai mult este acest depozit