我试图弄清楚为什么这不起作用。
我在打字稿上使用React和Redux。
我有以下代码:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {Action} from 'redux';
/** Redux Action **/
class AddTodo implements Action {
type: string;
id: number;
text: string;
constructor(id: number, text: string) {
this.type = 'ADD_TODO';
this.id = id;
this.text = text;
}
}
// ...
class TodoApp extends React.Component {
public render(): JSX.Element {
return (
<div>
<button onClick={() => {
store.dispatch(new AddTodo(0, 'Test'));
}}>
Add Todo
</button>
</div>
);
}
}
// ...
当我点击按钮时,我在控制台上收到以下错误:
未捕获错误:操作必须是普通对象。使用自定义中间件进行异步操作。
我不明白Redux为什么认为这是异步动作或复杂对象。
我的减速器甚至没有被执行。它们看起来像这样:
const todoReducer: Reducer<Todo> = (state: Todo, action: Action): Todo => {
if (action instanceof AddTodo)
return { id: action.id, text: action.text, completed: false } as Todo;
// ...
else
return state;
};
const todosReducer: Reducer<Todo[]> = (state: Todo[] = [], action: Action): Todo[] => {
if (action instanceof AddTodo)
return [...state, todoReducer(undefined, action)];
// ...
else
return state;
}
如果我传入{ type: 'ADD_TODO', id: 0, text: 'Test' }
而不是new Action(0, 'Test')
,则错误消失,但由于减速器上的条件,我的操作未正确执行。
你知道这里发生了什么吗?
答案 0 :(得分:1)
丹·阿布拉莫夫本人解释道:
https://github.com/reactjs/redux/issues/992
基本上,如果使用我的方法,操作(记录/重放功能)的序列化和反序列化将不起作用,因为类型信息不会持久存在。
引用丹:
换句话说,这是一种反模式:
function reducer(state, action) {
if (action instanceof SomeAction) {
return ...
} else {
return ...
}
}
如果我们让TypeScript用户成为可能,我知道JavaScript用户会受到诱惑并会滥用它,因为许多来自传统OO语言的人习惯用这种方式编写代码。然后他们将失去Redux中记录/重播的好处。
Redux的一个要点是强制执行一些我们认为重要的限制,如果没有强制执行,则不允许以后使用丰富的工具。如果我们让人们使用类来执行操作,他们就会这样做,并且实现像redux-recorder这样的东西是不可能的,因为不能保证人们使用普通的对象操作。特别是如果样板项目突然决定采用类,因为“哇,现在允许它,它一定是个好主意”。