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"""
Related
so when I create a class I it ususally look something like this
export default class SettingsIndex extends Component {
constructor(props) {
super(props);
this.state = {
testValue: 1,
};
}
myfunction(){
this.setstate({value: 2)
}
render(){
return(
........
Question 1:
To be honest, I am not sure when I really need to have the constructor, in my understanding is that I need to declare the constructor every time a class is receiving props from a parent component, is that assumption correction?
Question 2:
see myfunction() in some classes it works without issue, however in some classes I have I get an error saying ```this.myfunction' is undefined and I then I need to bind(this) in the constructor like this
this.myfunction= this.myfunction.bind(this);
I am not sure why in some class this is accessible and not other, any idea?
You need to use the constructor only when you need to have some initialisation logic which needs to run before the first render such as initialising refs, state or binding functions. You do not require constructor just beecause your component is receiving props, React itself can do that prop forwarding for you
For your case you can define state as a class initialiser too with proper babel setup and get rid of the constructor
export default class SettingsIndex extends Component {
state = {
testValue: 1,
};
myfunction(){
this.setstate({value: 2)
}
}
Now as far as the question about binding is concerned, you first need to understand how does a function receive its context or this variable.
The this argument to a function call is received as the reference of the object on which the function is called unless the function is defined as an arrow function in which case it inherits the this variable from its surrounding scope or this is explicitly overwritten by use of call, apply or bind methods
For Example, in the lifeecycle meethods of React, the this variable already points to the class instance and calling a function using this.myFunction() will causee the myFunction to receive the context of the class as the object on which it is called is this.
On the other hand when you assign the function to an event handler, you are assigning a reference to it and when the event occurs the function is ccalled on the window reference causing the this to be undeefined and thus nneeding you to use arrow function or explicit bind to supply proper context.
Check this SO post for more details on this keyword
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.
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.
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.
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.