Reputation: 2433
This always worked great for me in React class components:
let myValue: string = "Hello World";
<Button onClick={this.handleClick.bind(this, myValue)}></Button>
I found this syntax in the React Hooks documentation and I like it, but it does not always pass back a value:
<Button onClick={handleClick} value={myValue}></Button>
This syntax works, but is hard to type and looks messy:
<Button onClick={() => handleClick(myValue)}></Button>
This is yet another way that works with hooks, but seems hacky to me.
<Button onClick={handleClick.bind(null, myValue)}></Button>
I'm confused by too many choices. Is there not just some best practice way of doing this?
Upvotes: 11
Views: 11646
Reputation: 222503
This is perfectly suitable way to do this:
<Button onClick={() => handleClick(myValue)}></Button>
The only downside is that onClick
prop has new value on each render and triggers a re-render of child component - even if it's pure. This may or may not cause performance problems depending on specific component; this will be a problem if there are many Button
instances or their re-renders are expensive.
If a value is static, a callback can be defined as constant function outside a component:
// outside function component
const myValue = "Hello World";
const myHandleClick = () => handleClick(myValue);
...
// inside function component
<Button onClick={myHandleClick}></Button>
If a value is dynamic and is available only inside a component, a function can be defined inside a component and memoized with useMemo
or useCallback
hook (as another answer already mentions):
// inside function component
const myHandleClick = useCallback(() => handleClick(myValue), [myValue]);
...
<Button onClick={myHandleClick}></Button>
Upvotes: 18
Reputation: 112787
The first and last versions in your question both create a new function, so if you can get away with just giving the function handleClick
to a prop, you should do that.
If you need to pass arguments to the function you can still use your first version in function components, but since this
is not used, you can just set it to null
.
<Button onClick={handleClick.bind(null, myValue)}></Button>
Upvotes: 6