Arrow function should not return assignment?

JavascriptReactjsEslint

Javascript Problem Overview


My code is working correctly in the app however, my eslint isn't liking it and is saying I should not return assignment. What is wrong with this?

<div ref={(el) => this.myCustomEl = el} />

Javascript Solutions


Solution 1 - Javascript

The Fix:

<div ref={(el) => { this.myCustomEl = el }} />

The Explanation:

Your current code is equivalent to:

<div ref={(el) => { return this.myCustomEl = el }} />

You are returning the result of this.myCustomEl = el. In your code, this is not really a problem -- however, one of the most frustrating bugs in programming occurs when you accidentally use an assignment (=) instead of a comparator (== or ===), for instance:

// This function will always return **true**, surprisingly
function isEqual(a, b) {
  // The warning would be thrown here, because you probably meant to type "a===b". The below function will always return true;
  return a=b;
}

let k=false;
let j=true;

if(isEqual(k,j)){
  // You'll be very, very, very confused as to why this code is reached because you literally just set k to be false and j to be true, so they should be different, right? Right?
  thisWillExecuteUnexpectedly();
}

In the above case, the compiler warning makes sense because k=true evaluates to true (as opposed to k===true, which is probably what you meant to type) and causes unintended behavior. Thus, eshint notices when you return an assignment, assumes that you meant to return a comparison, and lets you know that you should be careful.

In your case, you can solve this by simply not returning the result, which is done by adding enclosing brackets {} and no return statement:

<div ref={(el) => { this.myCustomEl = el }} />

You can also adjust the eshint warning like so: https://eslint.org/docs/rules/no-return-assign

Solution 2 - Javascript

You're implicitly returning an assignment. this.myCustomEl = el is an assignment. You could fix this linting error by changing your arrow function to (el) => { this.myCustomEl =el } which is no longer implicitly returning because you wrapped it in {} instead of ().

Side note: Declaring an arrow function inline inside a render method will break a PureComponent because every time your component renders it has to declare a new anonymous function, so the shallow props comparison that a PureComponent does is broken by this and will always re-render.

Try making that a method of your component.

class MyClass extends React.PureComponent {
    getRef = (el) => { this.ref = el; }

    render() {
        return <div ref={this.getRef} />;
    }
}

If the above syntax doesn't work for you, you can use the following:

class MyClass extends React.PureComponent {
    constructor(props) {
        super(props);

        this.ref = null;

        this.getRef = this.getRef.bind(this);
    }

    getRef(el) {
        this.ref = el;
    }

    render() {
        return <div ref={this.getRef} />;
    }
}

Solution 3 - Javascript

Just wanted to note something I came across. I have Prettier installed and it kept taking away my parens, resulting in eslint error: To confirm this I added a prettier-ignore:

    <div>
        {/*prettier-ignore*/}
        <Map
            ref={(m) => {
                this.leafletMap = m;
            }}
            center={mapCenter}
            zoom={zoomLevel}
        >
            <TileLayer
                attribution={stamenTonerAttr}
                url={stamenTonerTiles}
            />
        </Map>
    </div>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAnnaSmView Question on Stackoverflow
Solution 1 - JavascriptAidan HoolachanView Answer on Stackoverflow
Solution 2 - JavascriptKyle RichardsonView Answer on Stackoverflow
Solution 3 - JavascriptChristopher AdamsView Answer on Stackoverflow