redux-toolkit
redux-toolkit copied to clipboard
State from `createReducer` is not frozen in development, neither typed as `readonly`
This comes from https://github.com/mastodon/mastodon/pull/34573
In a component, there was a call to replies.reverse(), with const replies = useState(state => state.contexts.replies).
The contexts reducer is defined here: https://github.com/mastodon/mastodon/blob/main/app/javascript/mastodon/reducers/contexts.ts#L126
This caused errors in production as the object was frozen, but did not cause errors in development. This was not caught by Typescript either, as replies has a string[] type, not marked as readonly.
So two questions / issues:
- is there any reason
createReducerdoes not returnImmutable<State>? I understand that Immer does not do that automatically for compatibility with non-immutable types, but maybe RTK should? Or at least mention this in the Typescript documentations - is it expected that objects are not frozen in development, but are in a production build? This is surprising and I could not find any documentation about it (neither from RTK or Immer)
Yeah, that is surprising. Immer has frozen in dev mode for a long time, and then also started freezing in prod to (to let it prune needing to go through the entire state tree). So, it should be getting frozen, and that should be throwing an error.
Any chance of a smaller repro?
Per the TS types: we've never done anything to mark the store state as "immutable" or "readonly" at the TS level, even with use of Immer. There is a somewhat similar open issue over in the Reselect repo with someone suggesting it would be worth doing that for similar reasons:
- https://github.com/reduxjs/reselect/issues/737
We've discussed it a bit internally and are somewhat reluctant to make that kind of change in case it would have ripple effects across the ecosystem, but it could be worth investigating further.
Closing as we never got a repro. If you can pull one together, happy to take a look!