我使用Redux已经有一段时间了,但是我仍然看不到操作和减速器的意义。
正如在文档中所描述的,减速器可以概括为(previousState, action) => newState。同样的原理也适用于React的useReducer。
因此,这个减速器功能基本上处理所有的动作,这似乎违反了单一责任原则。我相信这样做是有充分理由的,但我看不出来。
对我来说,每个动作只需要一个函数就更有意义了。因此,与其使用ADD_TODO操作,不如使用addTodo(previousState, todoText) => newState函数。这将减少(不打算使用双关语)大量的样板代码,甚至可能带来轻微的性能改进,因为您不再需要通过操作类型进行switch。
,所以我的问题是:,与单动作函数相比,使用还原剂有什么好处?
发布于 2020-04-01 12:59:20
那么,如果您的问题是,我们为什么要使用reducers呢?
Flux的真正样板是概念性的:需要发出更新,需要向Dispatcher注册Store,需要将Store作为对象(以及需要通用应用程序时出现的复杂情况)。
这是redux的基本设计选择,因为它是受flux启发的。
如果你不喜欢switch的情况,还有减速机的尺寸。您可以在下面这样做:
export const todos = createReducer([], {
[ActionTypes.ADD_TODO]: (state, action) => {
const text = action.text.trim()
return [...state, text]
}
})上面是一个函数,它允许我们将还原器表示为从动作类型到处理程序的对象映射。
createReducer可以定义为:
function createReducer(initialState, handlers) {
return function reducer(state = initialState, action) {
if (handlers.hasOwnProperty(action.type)) {
return handlers[action.type](state, action)
} else {
return state
}
}
} 您可以在此这里上阅读更多内容。
发布于 2022-07-27 14:09:10
实际上,这是一个愚蠢的设计,没有任何意义。
这只是一种过度的工程。因为在大多数情况下,您只需要使用一个更简单的函数来更新状态,而不是以愚蠢的方式将其变成两个函数(还原函数和操作函数)。
通过在您的项目中采用redux,您可能会编写大量的还原器和操作代码,这些代码看起来非常难看,很难进行代码评审。
试想一下,如果useState函数是通过redux方式设计的!
const [todos, setTodos] = useState([]) 这一行代码现在看起来像这样(大量丑陋的代码):
export interface TODO {
name: string
}
export interface ITodosAction {
type:
| "SET_TODOS";
payload: {
todos?: TODO[];
};
}
export default function todosReducer(
state: TODO[] = [],
action: ITodosAction
): TODO[] {
export function setTodos(todos: TODO[]): ITodosAction {
return {
type: "SET_TODOS",
payload: { todos }
};
}
const todos = useSelector(state=>state.todos)
dispatch(setTodos(["A", "B"]));如果useState变成这样,我们将不得不忍受使用react (感谢react的团队没有采用像redux这样的过度工程和愚蠢的设计)。
记住:当这个设计已经给你带来麻烦的时候,千万不要试图弄清楚为什么它是好的。我们使用redux不是因为redux很好(相反,它是我见过的最糟糕的设计),而是因为我们没有太多的选择
发布于 2020-04-01 12:06:09
我认为你没有意识到减速器是多么的灵活,你可以随心所欲地创造出它们中的许多:
const initialState = {
key: 'someValue',
key2: 'someValue',
key3: {
key31: 'someValue',
key32: 'someValue',
key33: []
}
}
// all the below reducers can live in separate files and only handle a single action, if they want, no switches involved at all
const key = (state = initialState.key, action) => { /* the logic to be performed at 'key' */ }
const key2 = (state = initialState.key, action) => { /* the logic to be performed at 'key2' */ }
const key31 = (state = initialState.key3.key31, action) => { /* the logic to be performed at 'key3.key31' */ }
const key32 = (state = initialState.key3.key32, action) => { /* the logic to be performed at 'key3.key32' */ }
const key33 = (state = initialState.key3.key33, action) => { /* the logic to be performed at 'key3.key33' */ }
const key3 = combineReducers({key31,key32,key33})
// this is the top level reducer for your store
const myTopLevelReducer = combineReducers({key,key2,key3});https://stackoverflow.com/questions/60970022
复制相似问题