简体   繁体   English

无法在 Typescript 中调度 redux 操作

[英]Unable to dispatch redux action in Typescript

I intend to create a simple counter using react redux in typescript.我打算在打字稿中使用 react redux 创建一个简单的计数器。

I have defined my store with actions and reducers in the following manner but not sure how to invoke dispatch with a specific action我已经按照以下方式使用操作和减速器定义了我的商店,但不确定如何使用特定操作调用调度

import * as React from 'react';
import { createStore, Action, Reducer } from 'redux';

export interface CounterState {
    counter: number;
}

export enum ActionTypes {
    INCREMENT = 'increment',
    DECREMENT = 'decrement'
}

export interface IncAction { type: ActionTypes.INCREMENT }
export interface DecAction { type: ActionTypes.DECREMENT }

export type CounterAction = IncAction | DecAction;

const reducer: Reducer<CounterState> = (state: CounterState = {counter: 0}, action: CounterAction) => {
    switch (action.type) {
        case ActionTypes.INCREMENT:
            return { ...state, counter: state.counter + 1};
        case ActionTypes.DECREMENT:
            return { ...state, counter: state.counter - 1};
        default:
            return state;
    }
};

let store = createStore(reducer, { counter: 0 });

Following is how my react component Counter looks like以下是我的反应组件Counter样子

interface IProps {}

interface IState {}

export default class Counter extends React.Component<IProps, IState> {

private unsubscribe: Function;

constructor(props: IProps, context?: any) {
    super(props, context);
}

componentDidMount() {
    this.unsubscribe = store.subscribe(() => this.render());
}

componentWillUnmount() {
    this.unsubscribe();
}

render() {
    const { counter } = store.getState();
    return (
        <div>
            <p>
                <label>Counter: </label><b>#{counter}</b>
            </p>
            <button onClick={e => store.dispatch('increment') }>+</button>
            <span style={{ padding: "0 5px" }} />
            <button onClick={e => store.dispatch('decrement') }>-</button>
        </div>
    );
}

} }

I am getting following error -我收到以下错误 -

ERROR in [at-loader] ./src/components/Counter.tsx:63:54 TS2345: Argument of type '"increment"' is not assignable to parameter of type 'AnyAction'. [at-loader] ./src/components/Counter.tsx:63:54 TS2345 中的错误:“增量”类型的参数不能分配给“AnyAction”类型的参数。

ERROR in [at-loader] ./src/components/Counter.tsx:65:54 TS2345: Argument of type '"decrement"' is not assignable to parameter of type 'AnyAction'. [at-loader] ./src/components/Counter.tsx:65:54 TS2345 中的错误:“decrement”类型的参数不可分配给“AnyAction”类型的参数。

Look at the actual type definition of Action and AnyAction :查看ActionAnyAction的实际类型定义:

export interface Action {
  type: any;
}

export interface AnyAction extends Action {
  // Allows any extra properties to be defined in an action.
  [extraProps: string]: any;
}

It needs to be an object and it must have a type property NOT just a string .它必须是一个对象,并且必须有一个type属性,而不仅仅是一个string

You need an action creator that returns at a minimum an object with a type property.您需要一个至少返回一个具有type属性的对象的动作创建者。 You can also pass this object directly, which is what I assume you where attempting to do:您也可以直接传递此对象,这就是我假设您尝试执行的操作:

store.dispatch({type: ActionTypes.INCREMENT})

I would also recommend using the connect HOC to connect state to your component since doing const { counter } = store.getState();我还建议使用connect HOC 将状态连接到您的组件,因为执行const { counter } = store.getState(); will not trigger a re-render when the counter value in your store changes.当您商店中的计数器值更改时,不会触发重新渲染。 If you want a more basic example:如果你想要一个更基本的例子:

...
  this.unsubscribe : () => void

  componentDidMount() {
    this.unsubscribe = store.subscribe(() => this.setState({ store.getState() }))
  }

  componentWillUnmount() {
    this.unsubscribe()
  }
...

Then reference the component's local state in render via const { counter } = this.state;然后通过const { counter } = this.state;render引用组件的本地状态const { counter } = this.state;

I "fixed" this by doing this:我通过这样做“修复”了这个:

const _ = (state: any = 0, _: AnyAction) => state;
const root = combineReducers({
    _,
    applicationStatusReducer,
    ...
});

It seems to fix the issue if you just add an empty reducer with the action type of "AnyAction" to it.如果您只添加一个动作类型为“AnyAction”的空减速器,它似乎可以解决这个问题。

Obviously this isn't actually fixing the underlying issue, but for people who are content with the result of the fix above, this is a dirty way to do it.显然,这实际上并没有解决根本问题,但对于对上述修复结果感到满意的人来说,这是一种肮脏的方法。

Use at your own discretion.自行决定使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM