'pass parameters to a javascript function without using an inline function inside jsx
So after reading a few articles on react native performance, I realized that you're supposed to avoid arrow functions inside JSX. https://blog.codemagic.io/improve-react-native-app-performance/#avoid-arrow-functions
But I have the following react-native code
function Layout() {
function handlePress(index) {
console.log("Inside HandlePress", index)
// I want index here
}
function NavItemIterable(item, index) {
return(
// how to pass index without arrow functions
<Pressable key={index} onPress={handlePress}>
<NavItem />
</Pressable>
)
}
return(
<Box>
{data.map(NavItemIterable)}
</Box>
)
}
With arrow functions, I could do something like
<Pressable key={index} onPress={()=> handlePress(index)}>.
How can I avoid an arrow function is this case & still call handlePress with index.
(or should I even try to avoid)
Solution 1:[1]
That blog post you have mentioned is at least misleading, and doesn't give sufficient context to understand it's statement (e.g. why you would even use a nested function in that case at all).
Your example (a function component) is fundamentally different to the one in that blog post (a class component).
In your example, it is ok to use a function to "pass" the parameters to the handler.
That is generally inline with common react principles, and it doesn't matter a lot if you are using
an arrow function (const f = () => {};) or a classic function (const f = function(){};). (optimizations are still possible.)
What the blog post says, and doesn't say ...
The blog post states that you should "Avoid Arrow Functions", and gives an example.
In that example there is a difference between using a classic and an arrow function, but that isn't the actual problem, and the blog post doesn't say why you would use an extra function there at all (no matter if classic or arrow function) ?
class MyClass extends React.Component {
addTodo() {}
render() {
return <>
<MyComponent onClick={ () => this.addTodo() /* <-- Why would you even do this ? ... */ } />
<MyComponent onClick={ function(){ this.addTodo() } /* <-- ... even with a classic function ? */ } />
<MyComponent onClick={ this.addTodo } /> /* <-- Recommended. */
</>;
}
}
Of course, you should avoid that extra function, if there is no reason to add it.
What the blog post probably means ...
A common reason to use an extra function there is to capture the this context of the class. Indeed, here you need to use an arrow function.
In this example, only the arrow function will work (and the alternative), because it captures the this context of the component:
class MyClass extends React.Component {
myValue = 'some value';
addTodo(){
try { console.log( 'ok, value is:', this.myValue ); }
catch(_){
console.error( 'error: `this` is:', this );
}
}
render() {
const capturedThis = this;
return <>
<button onClick={ () => this.addTodo() } > arrow: works. </button>
<button onClick={ this.addTodo } > no extra function: error. </button>
<button onClick={ function(){ this.addTodo(); } } > classic function: worse error! </button>
<button onClick={ function(){ capturedThis.addTodo(); } } > classic alternative: works. </button>
</>;
}
}
What the blog post missed ...
The captured this context ("closure") might cause problems. That is probably why the blog post recommends to avoid it.
But the actual recommendation should not be to "avoid arrow functions", but to avoid capturing the this context in a closure (which is usually done by using an arrow function).
A solution would be to bind the method to the component:
class MyClass extends React.Component {
constructor(props){
super(props);
this.addTodo = this.addTodo.bind(this); // <-- bind method to the components `this`
}
myValue = 'some value';
addTodo(){
console.log( 'ok, value is:', this.myValue );
}
render() {
return <>
<button onClick={ this.addTodo } > works without arrow function </button>
</>;
}
}
Remark:
I would recommend that you just should forget that you have ever read the misleading recommendation in that blog post, and find better sources of knowledge.
I think closures, the .bind(this) pattern and optimizing functional components are beyond the scope of this question topic.
If you still want to optimize your functional component, unrelated to that blog post, then I think you should ask a new question.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | kca |
