Redux usage examples are very confusing and should be rewritten
See original GitHub issueHi, I’m a Redux maintainer. A Redux user just pointed me to https://storybook.js.org/tutorials/intro-to-storybook/react/en/data/ , which contains the following Redux reducer example:
// All our reducers simply change the state of a single task.
function taskStateReducer(taskState) {
return (state, action) => {
return {
...state,
tasks: state.tasks.map(task =>
task.id === action.id ? { ...task, state: taskState } : task
),
};
};
}
// The reducer describes how the contents of the store change for each action
export const reducer = (state, action) => {
switch (action.type) {
case actions.ARCHIVE_TASK:
return taskStateReducer('TASK_ARCHIVED')(state, action);
case actions.PIN_TASK:
return taskStateReducer('TASK_PINNED')(state, action);
default:
return state;
}
};
While this code runs, it is very unconventional. I’ve never seen a pattern where a reducer returns other reducers in the form of closures, and it’s never been something we’ve ever shown in our docs. This could easily be rewritten to be much clearer.
On top of that, the form of Redux logic shown here is very outdated. We now teach Redux Toolkit as the default approach for writing Redux logic:
- https://redux.js.org/tutorials/fundamentals/part-8-modern-redux
- https://redux.js.org/tutorials/essentials/part-2-app-structure
I realize that teaching Redux isn’t the focus of this page, but I’d really appreciate it if you could update this page to show more standard Redux patterns in some way - either switching to use createSlice
from Redux Toolkit, or at least removing the strange “closure reducer” pattern and just handling the logic directly inside of taskStateReducer
.
Issue Analytics
- State:
- Created 2 years ago
- Comments:5
Top GitHub Comments
Sure. A really short example might be:
Changes:
configureStore
instead ofcreateStore
createSlice
instead of a hand-written reducerstate
field”, I rewrote this to be a single action case that expects an action like{type, payload: {id, status}}
, and you’d dispatch it as:dispatch(taskStateUpdated({id: task.id, status: 'TASK_ARCHIVED'})
or similar.It’s also worth noting that we no longer teach the “container/presentational” pattern in our docs, especially now that we do teach the React-Redux hooks API as the default instead of
connect
. Some quick references:Not sure I have time to do an actual PR and update the docs myself, but hopefully that provides some pointers to the approaches we currently recommend, and I’m happy to answer if there’s more questions here. (also I tweeted this issue earlier today, and hopefully someone else might pop in and offer to do the actual PR work.)