JavaScript when not to pass callbacks - javascript

I am confused when I should be passing callbacks to functions. For example,
<div onMouseEnter={handleMouse} /> or <div onMouseEnter={() => handleMouse()} />
I didnt need the callback value that comes with onMouseEnter so I passed it as the second option and my boss said to do it like the first way. Im not sure why because would it just be passing on unused data?

Passing an arrow function as a prop will cause creating a new function every time the render is called and it's an anti-pattern in react.
See: https://reactjs.org/docs/faq-functions.html#is-it-ok-to-use-arrow-functions-in-render-methods

You're passing a callback with either approach.
The difference is that handleMouse always passes the existing handleMouse function and that () => handleMouse() creates a new function which does nothing except call handleMouse … and it creates another new function every time the component is rendered.

Related

React - What's the difference between {doThisFunc} , {doThisFunc()} and {()=>doThisFunc()} as onClick parameter?

I'm completely new to react and kind of mediocre in JS. Just want to know what's the difference between giving a button these parameters for its onClick event :
onClick={doThisFunc}
onClick={doThisFunc()}
onClick={() => doThisFunc()}
Recently I just got a bug where I call a function with parameter like onClick={doThisFunc(a)} and the application went "Too many re-renders. React limits the number of renders to prevent an infinite loop". But then I changed it to onClick={() => doThisFunc(a)} and It works perfectly.
Sorry for such beginner question and many Thanks for your feedback!
onClick={doThisFunc}
This means "pass the function into the onclick prop". Later, when the click happens, react will call doThisFunc, passing in the click event. This is usually the right thing to do, assuming you want the function to receive the click event.
onClick={doThisFunc()}
This means "call the function immediately, and pass its return value into the onclick prop". This is usually a mistake. You would only do this if doThisFunc was a factory that creates click-handler functions, which is rare.
onClick={() => doThisFunc()}
This means "create a new function with the text () => doThisFunc(), and pass it into onClick". Later, when the click happens, react will call your new function, which will in turn call doThisFunc.
This approach is sometimes just a more verbose way of getting the same end result as option 1. But it does have the benefit that you can pass whatever values you want into doThisFunc, so if you want something other than the event to be passed in, you would use this.

What does function re creation means? How bad it is?

What does javascript re-create function every time when component re-render means?
I am basically referring to the following code.
This way of invoking function recreate function
onChange={() => this.someFunction() }
Where as this is not
onChange={this.someFunction}
I basically needs to understand how Javascript re create the functions or when it wont re create function.
Any explanation or reference guide will be highly appreciated.
Thanks a lot in advance.
your onChange prop needs a function which will be triggered when the user makes changes .
when you have this onChange={() => this.someFunction()} you are passing a function to the onChange which is correct . But now when there is a re-render we are re-creating a brand new function () => this.someFunction() again and assigning it to your onchange prop .
whereas when you have this onChange={this.someFunction} you have already created a class method named someFunction and passing it to the onChange.
The major difference between the 2 is that in your component which uses the inline function (() => this.someFunction()) your this.props.onChange === prevProps.onChange will always be false because you are creating a new function for each re-render and since function in JS are nothing but objects your reference which onChange holds will keep changing each time.

Using .bind() in functional React component, is it recommended?

I saw this syntax below during our code review, it's my first time seeing it, I couldn't find any article online of it being used/recommended - usually I would opt for arrow function or useCallback in this use case. Just curious if anyone else here used this, and if yes, would you be able to provide some references or an article saying it's safe or recommended to use it.
function DummyComponent({ onBtnClick }) {
const [data, setData] = useState('some-data-that-only-exists-here');
return (
<div>
<button onClick={onBtnClick.bind(null, dummyData)} />
</div>
)
}
I was told that this prevents the function from being recreated on rerenders. Also, during writing of tests, it passes a class which seems to be the class of the HTML button as the 2nd argument when onBtnClick is triggered which is one of the reason why I didn't approve of this and needed some references.
While it's technically possible, the use of .bind or .call or .apply instead of an anonymous function is usually done to change the this inside the function. Here, you don't care about this, so it'd probably make a bit more intuitive sense to read and write if you used an anonymous function instead.
<button onClick={() => onBtnClick(dummyData)} />
Or make a higher-order function outside, before returning the JSX:
const makeOnBtnClick = arg => () => onBtnClick(arg);
<button onClick={makeOnBtnClick(dummyData)} />
I was told that this prevents the function from being recreated on rerenders.
No, a new function is created every time the render part (with the .bind runs), so a new function gets attached as the click handler every time. If this is something you're really worried about (which you probably shouldn't be), useCallback would be one way to have a more persistent function that doesn't have to be removed/recreated when rendering - just like you mentioned.

Calling a method vs using a function to call a method

Suppose we have a method inside a class like this
class Blog extends Component {
postClicked = (id) => {
this.setState({selectedPostId: id})
}
render () {
const newPosts = this.state.posts.map(el => {
return <Post key={el.id}
title={el.title}
author={el.author}
onClick={this.postClicked(el.id)}/>
})
return
//something
{post}
}
}
}
Now, What is the difference between calling the handler like this
onClick={this.postClicked(el.id)} and onClick={() => this.postClicked(el.id)}
Would appreciate if someone can tell me the difference in general
after Ecmascript 6 javascript was introduced with is arrow function link
here ()==>{//code} is a similar as a function() or anonymous function
tell me if you find out what you want
The first option, "this.postClicked(el.id)", will actually call the method, "this.postClicked", with the "el.id" argument, each time the component renders (probably not what's intended).
The second option, "() => this.postClicked(el.id)", will only call the method, "this.postClicked", with the "el.id" argument, when "Post" is clicked.
Overall, if you can find a way to put the "el.id" argument into an "id" or "name" prop on the component
<Post id={el.id} />
then you can do:
<Post
id={el.id}
onClick={this.postClicked}
/>
this.postClicked = (event) => {
const { id } = event.target;
...
}
This last option avoids the use of an unnamed function. If you use an unnamed function, it will cause unnecessary re-renders. React cannot tell that an unnamed function is the same when it's checking whether or not it should re-render, by considering if the props of a component have changed. It considers the unnamed functions to be a new prop each time it checks, causing an unnecessary re-render each time.
Overall, it won't break your app, but it slows down performance slightly if you do it enough. It comes up especially if you start using React Motion (you'll really notice a difference there). It's best to avoid unnamed functions if possible.
you can read this blog it wil clear the things https://medium.com/#machnicki/handle-events-in-react-with-arrow-functions-ede88184bbb
Differences are,
First method is a wrong implementation and it wont give the intended result, where as second one will work.
In the first method you are making a function call, in second one you are assigning a function's signature to onClick.
It is like the combination of below two statements.
var variableName = function(){//some content};
onClick={variableName}
It looks like you question has already been answered. Just a side note though: remember that when assigning your method with an arrow function
onClick={ () => this.method() }
a new anonymous function is created on every re-render. So if the method doesn't need any arguments, it's better to reference the method directly (without parentheses so it's not invoked).
onClick={ this.method }
The first will call the function every time render is done.
The second will do what you want - call it onClick.

react-native - calling functions as arguments

I've got a sneaking suspicion this question might be more todo with JavaScript and/or specifically ES6 than React-Native but I'll try. I have got the following component:
export default class Body extends Component {
componentWillMount() {
this.refresh();
}
clickme() {
console.log('I have been pressed!!!!!');
}
refresh() {
this.props.populateGrid();
}
render() {
return (
<View style={styles.body}>
<Grid inGrid={this.props.grid} />
<Button
onPress={this.clickme}
title={'PressMe'}
/>
</View>
);
}
}
First, I passed 'this.clickme()' to onPress. It didn't work. It was only after removing the braces it started working. Why? Don't we usually call a function including the ()? Also sometimes, you have to pass it in the following format something={() => this.clickme()}. Why/When?
So when do we call function as:
1. {this.clickme}
2. {this.clickme()}
3. {() => this.clickme()}
Thank you.
Short answer:
1 and 3 as you define in your question are effectively the same for Button.onPress -- they are passing in references to function bodies. However, #3 is also defining a new function inline, though it is defined in a very lightweight way. #2 is attempting to call the function inline. You might want to do this (#2) in some cases where you need to pass a number or boolean or string value to a property rather than a callback function as Button.onPress requires.
Longer answer:
The syntax required is defined by the signature of the method you're passing data to on the react component. In this case, we're talking about Button.onPress, which has the signature () => {} -- which means it takes in a callback function and won't pass any arguments to it when called. You don't want to call the function immediately, since the user is not clicking when you define the component. They are clicking some random time later.
Since you need to pass in a function and not its result, you don't want to include the () at the end of the function name. The parentheses will cause the function to be run immediately, whereas the name alone will simply pass a reference to the function body. That reference will be later called by Button.onPress to handle the user interaction.
A lot of JavaScript (and React) is written with a pattern of passing around function references and later calling those functions from within other functions. If you're not familiar with that pattern, definitely spend some time reading about callback patterns.
() => {} is also a shorthand way to define an inline anonymous function. It's called an arrow function, and it can have some performance gains over defining separate function bodies.
More info here:
() => {} (arrow function) documentation on MDN
Callback documentation on MDN

Categories

Resources