KadoBOT KadoBOT - 3 months ago 214
Javascript Question

Why JSX props should not use arrow functions

I'm running lint with my React app, and I receive this error

error JSX props should not use arrow functions react/jsx-no-bind


And this is where I'm running the arrow function (inside onClick):

{this.state.photos.map(tile => (
<span key={tile.img}>
<Checkbox
defaultChecked={tile.checked}
onCheck={() => this.selectPicture(tile)}
style={{position: 'absolute', zIndex: 99, padding: 5, backgroundColor: 'rgba(255, 255, 255, 0.72)'}}
/>
<GridTile
title={tile.title}
subtitle={<span>by <b>{tile.author}</b></span>}
actionIcon={<IconButton onClick={() => this.handleDelete(tile)}><Delete color="white"/></IconButton>}
>
<img onClick={() => this.handleOpen(tile.img)} src={tile.img} style={{cursor: 'pointer'}}/>
</GridTile>
</span>
))}


Is this a bad practice and should be avoided? And what's the best way to do it?

Answer

Using arrow functions or binding in JSX is a bad practice that hurts performance, because each render will create a new function, which means that the garbage collector will have more work than needed.

The best ES2015 way is to use bind in the constructor:

class whatever extends React.Component {
    constructor() {
        super();

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

    cb() {

    }

    render() {
        return (
            <button onClick={ this.cb }>Click</button>
        );
    }
}

You can also create a method using the Class Instance Fields, with an arrow function to get the same result. Class Instance Fields are a stage 1 proposal, so to use them add the Babel Stage 1 preset to your build environment.

class whatever extends React.Component {   
    cb = () => { // the class property is initialized with an arrow function that binds this to the class

    }

    render() {
        return (
            <button onClick={ this.cb }>Click</button>
        );
    }
}
Comments