Skip to content

Mutation in files Redux reducer #2186

Open
@lindapaiste

Description

@lindapaiste

I am working on setting up the Redux store using the @reduxjs/toolkit configureStore function, which automatically includes a lot of functionality such as thunk, dev tools, and a check for state mutations in reducers. That check immediately found one!

image

default:
return state.map((file) => {
file.children = sortedChildrenId(state, file.children);
return file;
});

The problematic code is in the default case of the reducer, which means that it runs every single time that an action is dispatched anywhere in the store (which is why the error showed up when handling an unrelated action). So that's not the right place. The sorting of children should happen only when children are added, removed, or renamed.

Alternatively, the store state could be unsorted and the sorting could be applied in a selector function. That would require changes to components which access the state.files directly, rather than through some selectFiles function which could sort.

I could try to fix the mutation within the current reducer code but this will be an extremely satisfying reducer to rewrite using Redux Toolkit (RTK). There are many changes to deeply-nested properties, and those are such a pain to write properly without mutations! It will be so much cleaner and nicer and easier to read if it's written using RTK, where you can mutate a draft version of the state. Related docs.

We actually have this same sort of mutation in multiple places, including the CREATE_FILE and UPDATE_FILE_NAME cases. This is a mutation because each file object in the mapped array is the same object instance as in the original array, and therefore cannot be modified. But that's hard to understand and I definitely think that best long-term solution is to use RTK.

return newState.map((file) => {
if (file.children.includes(action.id)) {
file.children = sortedChildrenId(newState, file.children);
}
return file;
});

return newState.map((file) => {
if (file.id === action.parentId) {
file.children = sortedChildrenId(newState, file.children);
}
return file;
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions