React passing parameter with arrow function in child component
You should pass a function itself to onClick
, not a result of the passed function invocation.
If you would like to invoke it with param, you have options:
- bind it with
item
withhandleClick.bind(this, item)
.bind
creates a new function will have a predefined first parameter -item
- pass new arrow function like
() => handleClick(item)
An example below:
export class ChildItem extends Component {
render() {
const { item, handleClick } = this.props;
return (
<div>
<a onClick={() => handleClick(item)} />
</div>
)
}
}
In your code you're invoking a function in onClick
declaration, so the result of handleClick
execution will be passed to onClick
, what is most likely not something you wanted to achieve.
<a onClick={handleClick(item)} />
Update:
as @dhilt wrote, there is a drawback of such approach. Since the newly created arrow function and .bind
also creates new function every time the render
method of ChildItem
is invoked, react will threat the resulted react element as a different, comparing to the previous "cached" result of render
method, that means that likely it might lead to some performance problems in the future, there is even a rule regarding this problem for eslint, but you shouldn't just follow this rule because of two points.
1) performance problems
should be measured. we don't forbid using Array.prototype.forEach
in favor of a regular for
because for
is the same or "faster".
2) definition of click handlers as class properties leads to increasing of the initializing step of the component instance. Re-render is fast and efficient in react, so sometimes the initial rendering is more important.
Just use what's better for you and likely read articles like this https://cdb.reacttraining.com/react-inline-functions-and-performance-bdff784f5578
Accepted answer has a performance hit: ChildItem
component will be re-rendered even if data hasn’t changed because each render allocates a new function (it is so because of .bind
; same with arrow functions). In this particular case it is very easy to avoid such a problem by getting handler and its argument right from the props
on new public class field:
export class ChildItem extends Component {
onClick = () => {
this.props.handleClick(this.props.item);
}
render() {
return (
<div>
<a onClick={this.onClick} />
</div>
);
}
}
ParentView
remains untouched.