我打算使用打字稿中的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>
);
}
}
我遇到以下错误-
[加载器]中的错误。/src/components/Counter.tsx:63:54 TS2345:无法将类型“ increment”的参数分配给类型“ AnyAction”的参数。
[加载器]中的错误。/src/components/Counter.tsx:65:54 TS2345:无法将类型为“减量”的参数分配给类型为“ AnyAction”的参数。
答案 0 :(得分:1)
查看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()
}
...
然后通过render
引用const { counter } = this.state;
中组件的本地状态
答案 1 :(得分:1)
我通过执行以下操作“修复”了该问题:
const _ = (state: any = 0, _: AnyAction) => state;
const root = combineReducers({
_,
applicationStatusReducer,
...
});
如果您仅向其添加一个动作类型为“ AnyAction”的空化器,则似乎可以解决该问题。
显然,这实际上并不能解决根本问题,但是对于那些对上述解决方案的结果感到满意的人,这是一种肮脏的方式。
自行决定使用。