[英]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
:查看Action
和AnyAction
的实际类型定义:
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.