question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

no-param-reassign with props, again

See original GitHub issue

Hello!

A comment regarding this change: #626 #627

While I agree in general that function parameters should not be mutated, this change gave me a lot of errors in code that I consider as safe. For example:

['foo', 'bar', 'qux', 'foo'].reduce((accumulator, value) => {
  accumulator[`_${value}`] = true;
  return accumulator;
}, {});

I know, I can change this rule in my .eslintrc or for this particular line of code. But this reduce pattern is quite common in JavaScript. Lodash has also a bunch of functions that work this way. There’s little risk mutating the accumulator since the reduce operation as a whole is non-mutating.

While the { "props": true } rule might catch some errors, it mostly produces false positives in my codebases. I’m already writing in a non-mutating, mostly pure functional style.

Related, the example in https://github.com/airbnb/javascript#7.12 isn’t helpful IMHO. The “good” and “bad” examples do not seem to match. The “bad” example mutates an object. The “good” example illustrates input normalization. Which is a different thing IMHO. 😉

Perhaps there are cases where people accidentally mutate parameters just to normalize input. Then a better example would be:

// bad
function f1(obj) {
  obj.key = obj.key || 1; // Mutate to normalize
  // Use obj.key
}
// good
function f2(obj) {
  const key = obj.key || 1; // Normalize without mutating
  // Use key
}

But I think people are mutating parameters not just accidentally, but more commonly to make changes on objects. For example:

function doSomethingWithObject(obj) {
  obj.hello = 'world';
  obj.list.sort();
  delete obj.foo;
}

Then, a good alternative would be a pure function. It could clone the input, then augment it. Or use a library for immutable data that has smart lists and hashes, like Immutable.js.

Assuming this case, a better example would be:

// bad
function f1(obj) {
  obj.key = 1;
}
// good
function f2(obj) {
  return Object.assign({}, obj, { key: 1 }); // Shallow clone
}

Or with prototypal delegation:

function f2(obj) {
  const obj2 = Object.create(obj);
  obj2.key = 1;
  return obj2;
}

(Or with a library like Immutable.js…)

I think the bottom line is that the topic of immutability is too complex to be covered in a simple example. And the rule no-param-reassign: [2, { "props": true }] cannot cover the nuances here. I propose to reconsider the switch to { "props": true }.

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Reactions:20
  • Comments:38

github_iconTop GitHub Comments

62reactions
ljharbcommented, Apr 11, 2016

You’re right, my mistake. I’ve updated my original comment.

Performance is the last and least important concern when programming - it’s easy to speed up clean code, but it’s hard to clean up fast code.

54reactions
ljharbcommented, Apr 11, 2016

This is a rule we use at Airbnb - in the reducer case, if the body of your reducer is return Object.assign({}, accumulator, { [key]: value }) then you’ll avoid mutation as well as satisfy the linter (both in spirit and in fact).

Mutation should be avoided in all its forms, and our style guide tries to be consistent with this belief.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to avoid no-param-reassign when setting a property on a ...
Personally, I would just use the "no-param-reassign": ["error", { "props": false }] approach a couple of other answers mentioned. Modifying a property of...
Read more >
no-param-reassign - ESLint - Pluggable JavaScript Linter
A pluggable and configurable linter tool for identifying and reporting on patterns in JavaScript. Maintain your code quality with ease.
Read more >
Update eslintrc no-param-reassign to allow props reassignment
Update .eslintrc.yml to allow prop reassignment for the rule no-param-reassign; Removes unused eslint-disable that this change caused.
Read more >
Airbnb JavaScript Style Guide()
Reassigning parameters can lead to unexpected behavior, especially when accessing the arguments object. It can also cause optimization issues, especially in V8.
Read more >
Writing Reducers with Immer | Redux Toolkit - JS.ORG
There are several reasons why you must not mutate state in Redux: ... include the https://eslint.org/docs/rules/no-param-reassign rule, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found