Redux-toolkit: Do we want to recommend the `no-param-reassign` eslint rule in the docs?

Created on 24 Apr 2020  路  19Comments  路  Source: reduxjs/redux-toolkit

I just had this idea when another user tried to assign to the state function argument.
There is actually an eslint rule for that:
no-param-reassign

I'd suggest we either add that rule as a recommendation somehwere in the docs or go even one step farther and create a shareable config package .

That way we could add some more recommended rules in the future.

I'm thinking of later-on adding a self-written eslint-typescript rule that disallows assigning to anything of the type Draft or something similar.

Most helpful comment

Now covered in our docs:

https://redux-toolkit.js.org/usage/immer-reducers#linting-state-mutations

All 19 comments

Pretty sure that rule also forbids mutating someParam.field = 123, which doesn't work well with Immer.

Only if you override the default configuration of { "props": false } to { "props": true }.
Over in https://github.com/immerjs/immer/issues/189, mwestrate essentially recommends the rule in its default config.

Long time user of redux here, new to RTK / Immer. Running into ESLint complaining that I'm reassigning state in createSlice. But this is fine though, right, because RTK is using produce under the hood? If so, how do you recommend using the no-param-reassign rule? I know you can do ignorePropertyModificationsFor, but in some cases I'd like to just completely rewrite state in the reducer, not just a property, for example if we're holding a loading on/off boolean.

const searchingSlice = createSlice({
  name: 'searching',
  initialState: false,
  reducers: {
    setStatus: (state, action: PayloadAction<boolean>) => {
      state = action.payload  // Error
    },
  },
})

Assigning state = never does anything useful. All that does is change what the local variable state is pointing to, which is always a no-op.

If you want to return a completely new state value / replace the existing state, you need to actually return it: return action.payload.

Ohhh okay, thanks much.

And that's exactly why I suggest recommending this eslint rule xD

So what does it mean to "suggest" it in this case, exactly? Where would we document that info? How would we encourage people to do so?

Hmm, that's the question.

Maybe in the style guide, hand-in-hand with the immer and RTK recommendations, and/or in the documentation for createReducer and createSlice?

That could work, yeah.

I'm interested to know what the proposed solution/information to be in the style guide would be here.

If you use the standard eslint setup and use an example from RTK such as:

const issuesDisplaySlice = createSlice({
  name: 'issuesDisplay',
  initialState,
  reducers: {
    displayRepo(state, action: PayloadAction<CurrentRepo>) {
      const { org, repo } = action.payload
      state.org = org                                     // <-- Error
      state.repo = repo                                 // <-- Error
    },

You would get the reassignment errors on the state. lines. What is the proposed solution here? Thanks

@StuartMorris0 that is most definitely not the standard eslint setup, as the props option to that rule defaults to false.
Are you extending some overly restrictive eslint config like the airbnb config? (Which in my personal opinion has outlived it's usefulness and is not a good default).

A correct configuration would be just no-param-reassign: "error" or no-param-reassign: ["error", { "props": false }] (which is equalivalent)

You're right it is the airbnb extends causing the issue, I have reverted the rule to its default.
"no-param-reassign": ["error", { "props": false }]

Thanks

Airbnb has outlived its usefulness and is not a good default

Yes, this, 馃挴 :)

Does anyone know of any other good defaults I could review please?

@StuartMorris0 I would start with https://www.npmjs.com/package/eslint-config-react-app .

Airbnb has outlived its usefulness and is not a good default

Yes, this, 馃挴 :)

If Airbnb rule set has outlived its usefulness, is there a newly recommended one? Thx!

@BenjiTheC what about the defaults that ship with eslint?
Or the one linked directly above your question.

What I normally do is

  • All my reducers are in a single directory called reducers.
  • Then I want to force the eslint to disable no-param-reassign for the reducers directory only.
  • Then I create a new eslint config file(.eslintrc.json) inside the reducers directory, and add "no-param-reassign": ["error", { "props": false }] to it.

so the .eslintrc.json inside reducers directory is like below

{
  "rules": {
    "no-param-reassign": ["error", { "props": false }]
  }
}

Now covered in our docs:

https://redux-toolkit.js.org/usage/immer-reducers#linting-state-mutations

Was this page helpful?
0 / 5 - 0 ratings