I am learning react and in some videos the lecturers use function like this in their component.
function(){}
and sometimes they use arrow function like this
function=()=>{}
what are the different between these two? whenever I use function(){} I cannot call any props from state so I always use arrow function and it works very well.
Arrow function automatically binds this-context to your component.
With the normal function you would need to do that yourself in your components constructor like that:
this.func = this.func.bind(this)
When using the "fat arrow" function, i.e. myFunc = () => {}, if you try to access this you will receive access to the surrounding function's this. This is because the fat arrow function does not bind it's own this.
When you use myFunc() {} you are binding this and scoping it to that function.
Related
I'm implementing a solution to a recent question I asked on here. However in order to make the logic work I must use a function. When I place the function below the constructor I get an error as shown below:
If I can't place it in the constructor, or the render method where is the correct place to put handler functions?
Consider This:
loginGetHandler() {
//...
}
If you use this declaration for your function, don't forget to bind it in the constructor as:
constructor(){
//....
this.loginGetHandler = this.loginGetHandler.bind(this);
}
Or as ES6 Named Arrow Function:
loginGetHandler = () => {
//...
}
You will be needing no binding here as ES6 already does that for you.
Does anyone know what happened to 'this'?
console.log('check 1', this) //{activateLasers: ƒ, …}
Object.keys(modelData).forEach(function(key, index1) {
console.log('check 2', this) //undefined
The context of this changes inside map.
Array.prototype.map() takes a second argument to set what this refers to in the mapping function.
You can explicitly pass it to the map function to preserve the context.
array.map(function(i) {
...
} , this)
In your case
array.forEach(function(key, i) {
....
}, this)
Alternatively, you can use an ES6 arrow function to automatically preserve the current this context
array.map((i) => {
...
})
It looks like you're writing code in strict mode. this is undefined because that's how the language works.
this in javascript is a syntactic construct. When you call a class or object method you usually do it in a way that looks like obj.method(). The language sees the syntactic pattern with the . and () and makes this obj inside method. If you ever don't see that pattern, (and are not using an => function, it should be a good cue that this might be undefined or window.
We all know that we need to bind function in React to make it work. I do know why do we need to bind it.
But I'm not sure why we don't need to bind arrow function.
Example:
Using arrow function (No bind in required)
handleClick = () => {
this.setState({
isToggleOn: !this.state.isToggleOn
});
};
Now, Using function (Bind is required)
this.handleClick = this.handleClick.bind(this);
handleClick() {
this.setState({
isToggleOn: !this.state.isToggleOn
});
};
I'm not asking why we need bind in function. I just want to know why binding is not required in arrow function.
Thanks.
Simply because arrow function does not have the following in its context:
this
arguments
super
new.target
So when you reference this inside an arrow function it treat this as any other variable and look for its declaration in its scope first and it can not find it so it search the upper scope which is the this referring to the react component class which what is required so we do not need to bind the this to the class.
To quote MDN:
An arrow function expression has a shorter syntax than a function
expression and does not have its own this, arguments, super, or
new.target. These function expressions are best suited for non-method
functions, and they cannot be used as constructors.
Further,
Until arrow functions, every new function defined its own this value (based on how function was called, a new object in the case of a constructor, undefined in strict mode function calls, the base object if the function is called as an "object method", etc.). This proved to be less than ideal with an object-oriented style of programming.
So basically, the reason we don't need to bind is because this does not exist in the context of the arrow function. So, it goes up to the next level and uses the this it finds there.
When do I use an arrow function?
class App extends Component {
onButtonClick = event => console.log(click!)
}
and, When do I use a function of the class?
class App extends Component {
onButtonClick() {console.log(click!)}
}
First let's differentiate them,
Arrow functions do not require binding like normal functions.
They have a cleaner syntax.
They are not the standard way of coding in Reactjs.
If only a single statement is part of arrow function that it returns, you can omit curly braces.
Then, coming to usage...
Arrow function can be used for in a event handler where a value should be passed to the function, like onClick=dothis(arg)
To do this, you have to wrap the dothis function in another function like onClick=()=>dothis(arg), otherwise your event handler won't work as required.
I recommend using normal functions because Arrow functions are not mentioned in the standard documentation of Reactjs.
"""I prefer sticking to the standards"""
I'm reading Learning Redux by Daniel Bugl (which by the way is outstanding) and in the "FilterList component" section code example there is an action creator invocation that looks like this:
onClick={() => setFilter(category)}
and one like this:
onClick={clearFilter}
So it looks like when there are no arguments invocation works with just function name and when there are arguments then a more verbose syntax, in this case the arrow function syntax needs to be used. I'd like to verify this with the community here.
If I can do clearFilter just like that then why can't I do setFilter(category) without the arrow function syntax?
myFunction is a reference to a specific function, which can be passed around, assigned to a variable, etc. myFunction(...) is a call to a function. If you try to pass that, you'll be passing whatever that function call returned.
You can't do setFilter(category) because you'd be passing the result of that function call, not the function itself. That's why you wrap the call in an anonymous arrow function (() => {...}, where the curly braces are optional for simple functions), and pass that in.
While not specific to ES6 or React, you'd probably find it useful to learn more about JavaScript functions over at MDN web docs.
Because it's the difference between passing a reference to a function and calling a function. Remember that JSX gets transformed into a call to React.createElement(), and props get turned into an object. Here's how it looks:
// before
<SomeComponent
onClick1={clearFilter}
onClick2={() => setFilter(category)}
onClick3={setFilter(category)}
/>
// after
React.createElement(SomeComponent, {
onClick1 : clearFilter,
onClick2 : () => setFilter(category),
onClick3 : setFilter(category)
});
For onClick1, we're passing a reference to a named function. For onClick2, we're passing a reference to an anonymous function that calls another function when it runs. But, for onClick3, we're calling setFilter(category) as we render, and then using the result of that as the value for onClick3. That's not what you want.
Also, note that this actually has nothing to do with Redux and action creators. It's actually just about React, JSX, and how functions work in Javascript.