首页 文章

使用connect时使用redux-thunk键入错误

提问于
浏览
5

我正在使用redux和redux-thunk与typescript . 我试图通过connect()注入一个组件,一个简单的thunk动作创建者,使用mapDispatchToProps .

Actions

export enum TestActionTypes {
  THUNK_ACTION = "THUNK_ACTION"
}

export interface ThunkAction {
  type: TestActionTypes.THUNK_ACTION;
}

export type TestAction = ThunkAction;

Action Creators

export function thunkActionCreator() {
  return function(dispatch: Dispatch<any>) {
    dispatch({ type: TestAction.THUNK_ACTION });
  };

Connected Component

interface DemoScreenState {}

interface OwnProps {}

interface StateProps {}

interface DispatchProps {
  testThunk: () => void;
}

type DemoScreenProps = StateProps & DispatchProps & OwnProps;

class DemoScreen extends React.Component<
  DemoScreenProps,
  DemoScreenState
> {
  constructor(props: DemoScreenProps) {
    super(props);
  }

  componentDidMount() {
    this.props.testThunk();
  }

  render() {
    return null;
  }
}

function mapStateToProps(state: any): StateProps {
  return {};
}

function mapDispatchToProps(dispatch: Dispatch<any>): DispatchProps {
  return {
    testThunk: () => dispatch(thunkActionCreator())
  };
}

export default connect<StateProps, DispatchProps, OwnProps>(
  mapStateToProps,
  mapDispatchToProps
)(DemoScreen);

Store

import { createStore, applyMiddleware } from "redux";
 import rootReducer from "./RootReducer";
 import thunk from "redux-thunk";

 const store = createStore(rootReducer, applyMiddleware(thunk));

 export default store;

但是,在使用connect()时遇到两个问题 . 首先,我在mapDispatchToProps中获得了testThunk声明的类型错误 .

'(dispatch: Dispatch) => void'类型的参数不能分配给'Action'类型的参数 . '(dispatch: Dispatch) => void'类型中缺少属性'type' . 我不知道如何处理这个问题,因为根据定义,thunk与普通操作不同 .

*** EDIT 24/10/2018 *** cf下面的答案,使用:

"@types/react-redux": "^6.0.9",
"react": "16.3.1",
"react-native": "~0.55.2",
"react-redux": "^5.0.7",
"redux": "^4.0.1",
"redux-thunk": "^2.3.0"

1 回答

  • 2

    我终于设法得到一个正确输入的连接组件,主要是使用它作为起始点https://github.com/reduxjs/redux-thunk/blob/master/test/typescript.ts,用于正确的异步动作创建者输入 . 关键是要正确键入你的商店,并使用来自redux-thunk的ThunkDispatch和ThunkAction .

    Store.tsx

    import { createStore, applyMiddleware, combineReducers } from "redux";
    import { playground, IState } from "./reducer";
    import thunk, { ThunkMiddleware } from "redux-thunk";
    import { IActions } from "./actions";
    
    export interface RootState {
      playground: IState;
    }
    
    export type RootActions = IActions;
    
    const rootReducer = combineReducers({ playground });
    
    const store = createStore<RootState, RootActions, {}, {}>(
      rootReducer,
      applyMiddleware(thunk as ThunkMiddleware<RootState, RootActions>)
    

    Actions.tsx

    import { Action } from "redux";
    import { ThunkAction } from "redux-thunk";
    import { RootState, RootActions } from "./store";
    
    type ThunkResult<R> = ThunkAction<R, RootState, undefined, RootActions>;
    
    //Actions
    export enum TestActionTypes {
      THUNK_ACTION = "THUNK_ACTION",
    }
    
    export interface AsyncAction extends Action {
      type: TestActionTypes.THUNK_ACTION;
    }
    
    export type IActions = AsyncAction;
    
    //Action creator
    export function testAsyncActionCreator(): ThunkResult<void> {
      return (dispatch, getState) => {
        console.log(getState);
        dispatch({ type: TestActionTypes.THUNK_ACTION });
      };
    }
    

    Reducer.tsx

    import { IActions, TestActionTypes } from "./actions";
    import { Reducer } from "redux";
    
    export interface IState {}
    
    const defaultValue: IState = {};
    
    export const playground: Reducer<IState, IActions> = (
      state = defaultValue,
      action
    ) => {
      switch (action.type) {
        default:
          return state;
      }
    };
    

    ConnectedComponent.tsx

    ...
    import { connect } from "react-redux";
    import { RootState, RootActions } from "./redux/store";
    import { syncActionCreator, testGetState } from "./redux/actions";
    import { ThunkDispatch } from "redux-thunk";
    
    interface OwnProps {}
    
    interface StateProps {}
    
    interface DispatchProps {
      test: () => void;
    }
    
    type Props = OwnProps & StateProps & DispatchProps;
    
    class DumbContainer extends React.Component<Props> {
      render() {
        return (
          ...
        );
      }
    }
    
    
    const mapStateToProps = (state: RootState): StateProps => {
      return {
        text: state.playground.text
      };
    };
    
    const mapDispatchToProps = (
      dispatch: ThunkDispatch<RootState, undefined, RootActions>
    ): DispatchProps => {
      return {
        test: () => {
          dispatch(testAsyncActionCreator());
        }
      };
    };
    
    export default connect<StateProps, DispatchProps, OwnProps, RootState>(
      mapStateToProps,
      mapDispatchToProps
    )(DumbContainer);
    

    我这里也有一个游乐场项目https://github.com/vbvxx/playground-reactnative-typescript

相关问题