无法在 Typescript 中调度 redux 操作
Posted
技术标签:
【中文标题】无法在 Typescript 中调度 redux 操作【英文标题】:Unable to dispatch redux action in Typescript 【发布时间】:2018-12-10 20:12:06 【问题描述】:我打算在 typescript 中使用 react redux 创建一个简单的计数器。
我已经通过以下方式定义了我的商店,其中包含动作和减速器,但不确定如何使用特定动作调用调度
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 );
以下是我的反应组件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>
);
我收到以下错误 -
[at-loader] 中的错误 ./src/components/Counter.tsx:63:54 TS2345:“增量”类型的参数不可分配给“AnyAction”类型的参数。
[at-loader] ./src/components/Counter.tsx:65:54 中的错误 TS2345:“减量”类型的参数不可分配给“AnyAction”类型的参数。
【问题讨论】:
【参考方案1】:我通过这样做“修复”了这个问题:
const _ = (state: any = 0, _: AnyAction) => state;
const root = combineReducers(
_,
applicationStatusReducer,
...
);
如果你只添加一个动作类型为“AnyAction”的空reducer,似乎可以解决这个问题。
显然这实际上并没有解决根本问题,但对于满足于上述修复结果的人来说,这是一种肮脏的做法。
自行决定使用。
【讨论】:
【参考方案2】:查看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;
它必须是一个对象,并且它必须有一个 type
属性而不仅仅是一个 string
。
您需要一个至少返回具有type
属性的对象的操作创建器。你也可以直接传递这个对象,这是我假设你尝试做的:
store.dispatch(type: ActionTypes.INCREMENT)
我还建议使用connect
HOC 将状态连接到您的组件,因为当您的商店中的计数器值发生变化时,const counter = store.getState();
不会触发重新渲染。如果你想要一个更基本的例子:
...
this.unsubscribe : () => void
componentDidMount()
this.unsubscribe = store.subscribe(() => this.setState( store.getState() ))
componentWillUnmount()
this.unsubscribe()
...
然后通过const counter = this.state;
render
引用组件的本地状态
【讨论】:
我通过store.dispatch(type: ActionTypes.INCREMENT)
解决了这个问题。还必须在 counter 中解构 store.getState() 但仍然 counter 保持 0 i:(
我已经更新了我的答案,对于任何更复杂的问题,您确实需要使用react-redux
--> github.com/reduxjs/react-redux以上是关于无法在 Typescript 中调度 redux 操作的主要内容,如果未能解决你的问题,请参考以下文章
使用 typescript 将异步操作发送到 redux 调度
如何使用 redux-thunk 和 TypeScript 调度 ThunkAction
使用 TypeScript 在 React 组件外部调度 Redux Thunk 操作
Redux-Toolkit createAsyncThunk with Typescript