I am not great with JS and playing around with React.
The React docs located here state the following:
When implementing the constructor for a React.Component subclass, you
should call super(props) before any other statement. Otherwise,
this.props will be undefined in the constructor, which can lead to
bugs.
My question is HOW does this actually work? What is super() doing that magically enables this.props within my constructor?
In the documentation that you have mentioned. It is coded in ES6 standard of javascript.
So this statement
class Greeting extends React.Component
It means Greeting is inherting from React.Component, by calling super, you are actually calling the parent element with props parameter,
if you intend on using this.props inside the constructor, you have to call super(props)
Hope these links are helpful.
Related
I understand the concept of constructors in OOP languages like C++. However, I am not entirely sure when to use a constructor in REACT. I do understand that JavaScript is object oriented, but I am not sure what the constructor is actually 'constructing'.
When rendering a child component, do you need a constructor in the child component? For example:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
items: [],
error: null
}
}
render () {
return (
<React.Fragment>
<ChildComponent data={this.state.items}></ChildComponent>
</React.Fragment>
)
}
}
I will keep the example short for the sake of brevity. But, why would do you need a constructor? And would you need a constructor in the child component for props?
It is possible that my ES6 knowledge is not up to snuff.
If you don’t initialize state and you don’t bind methods, you don’t need to implement a constructor for your React component.
The constructor for a React component is called before it is mounted. When implementing the constructor for a React.Component subclass, you should call super(props) before any other statement. Otherwise, this.props will be undefined in the constructor, which can lead to bugs.
Typically, in React constructors are only used for two purposes:
Initializing local state by assigning an object to this.state.
Binding event handler methods to an instance.
https://reactjs.org/docs/react-component.html#constructor
A constructor function is NOT required at all.
State initialization can be done directly in the body of a class and function can be assigned to properties as described below, Technically these are known as class properties, it may land up soon in native javascript, yet because almost all of us use Babel transpiler for React projects, we can use that syntax
class Comp extends React.Component {
/*
* generally we do not need to put the props in state, but even if we need to.
* then it is accessible in this.props as shown below
**/
state={ first: 1, second: this.props.second }
handler= (token) => {
this.setState(prevState => ({first: prevState.first+1}));
}
render() {
return <div onClick={this.handler}>{this.state.first} and {this.state.second } </div>
}
}
Read more details about class properties and removing constructor from react class component over here.
https://hackernoon.com/the-constructor-is-dead-long-live-the-constructor-c10871bea599
Linke in your example, it's useful use constructor when you need to initialize your state, or bind some event-listener-function
<element onClick={this.handler} />
this.handler = this.bind.handler(this); inside the constructor
I know that this question was asked many times, but it is still doesn't clear.
Many people just said:
Pass props to constructor if you want to access this.props there
one more example of the answer
Oficial doc says Class components should always call the base constructor with props. , but if we do not pass props to constructor, we will still have this.props everywhere exept constructor.
Also from react source code we can see source code of the React.Component
function ReactComponent(props, context) {
this.props = props;
this.context = context;
}
But it is confuses me even more.
super() should be called with two parametrs: props and context . But we invoked our super empty and still have access two this.props.
According to ECMA documentation super() invokes parent constructor() with parametrs passed to super() . But our super() is empty.
So my questions are:
Why official docs says:
Class components should always call the base constructor with props.
How React set props to child component if super() and constructor() is empty?
Is it bug of feature of the React that props are accessible in child component without passing props to super() and constructor()?
Here is an answer from Dan Abramov:
But if we do not pass props to constructor, we will still have
this.props everywhere except constructor.
Yes, React sets this.props anyway after the constructor runs. Still, it is confusing to have this.props work in some places and not others. Especially if both constructor and other methods call some shared method that reads this.props. So, to avoid any potential confusion, we recommend always calling super(props).
Also from source code of Create Element you can see that createElement
adds props regardless if you use super(props)
createElement() has no relation to this question. It creates an element, not an instance.
So, to get back to your question, technically it's only necessary if you plan to access this.props in the constructor or any method you call from constructor. However it's pretty confusing to have to remember this. You might know about it and not call super(props), but the next person on your team will want to access this.props in a constructor and will be surprised it doesn't work. It's just easier to always specify it to avoid these problems.
If no constructor is defined in the code for a react component you can assume it will be automatically bound behind the scenes, such as:
constructor(props){
super(props);
}
Once you have explicitly defined a constructor you must remember to always put that code in otherwise it will be left out... you are basically just overriding a default method :)
Learning React from the docs and came across this example:
class Square extends React.Component {
constructor() {
super();
this.state = {
value: null,
};
}
...
}
According to Mozilla, super allows you to use this in the constructor. Is there any other reason to use a standalone super (I know super allows you to access parent class's methods as well) but with React is there any other use case of just calling super() by itself?
super() will call the constructor of its parent class. This is required when you need to access some variables from the parent class.
In React, when you call super with props, React will make props available across the component through this.props. See example 2 below
without super()
class A {
constructor() {
this.a = 'hello'
}
}
class B extends A {
constructor(){
console.log(this.a) //throws an error
}
}
console.log(new B())
with super()
class A {
constructor(props) {
this.props = props
}
}
class B extends A {
constructor(props) {
super(props)
console.log(this.props)
}
}
console.log(new B({title: 'hello world'}))
super() is called inside a react component only if it has a constructor. For example, the below code doesn't require super:
class App extends React.component {
render(){
return <div>Hello { this.props.world }</div>;
}
}
However if we have a constructor then super() is mandatory:
class App extends React.component {
constructor(){
console.log(this) //Error: 'this' is not allowed before super()
}
}
The reason why this cannot be allowed before super() is because this is uninitialized if super() is not called. However even if we are not using this we need a super() inside a constructor because ES6 class constructors MUST call super if they are subclasses. Thus, you have to call super() as long as you have a constructor. (But a subclass does not have to have a constructor.)
We call super(props) inside the constructor if we have to use this.props, for example:
class App extends React.component{
constructor(props){
super(props);
console.log(this.props); // prints out whatever is inside props
}
}
I hope I could make it clear.
Worth adding that super() is short for superclass contructor, a concept from inheritance.
By default the class Square inherits the constructor from its superclass React.Component.
The inherited constructor can be overridden by declaring a new constructor() method.
If the intention is to extend rather than override the superclass constructor then it must be explicitly invoked using super().
When implementing the constructor for a React.Component subclass, you should call super(props) before any other statement. Otherwise, this.props will be undefined in the constructor, which can lead to bugs.
In JavaScript, super refers to the parent class constructor.
Importantly, you can’t use this in a constructor until after you’ve called the parent constructor. JavaScript won’t let you:
But we forgot that if a function is called before the super() call had a chance to set up this.name. So this.name isn’t even defined yet! As you can see, code like this can be very difficult to think about.
To avoid such pitfalls, JavaScript enforces that if you want to use this in a constructor, you have to call super first. Let the parent do its thing! And this limitation applies to React components defined as classes too:
super(); is not required by react, but is mandated by ES6 subclass
To use this keyword we should use the super keyword before it. Why? super is used to call the parent class's constructor.
Now why do we need to call the parent's constructor? The answer is to initialize the properties values which we are referring through this keyword.
I'm learning react from the docs, but not sure what the super() does in this example. Usually, doesn't it take the arguments that are passed to making a new instance and then calls React.Component's constructor method to incorporate these arguments into the instance? What does it do without any arguments?
class LikeButton extends React.Component {
constructor() {
super();
this.state = {
liked: false
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({liked: !this.state.liked});
}
render() {
const text = this.state.liked ? 'liked' : 'haven\'t liked';
return (
<div onClick={this.handleClick}>
You {text} this. Click to toggle.
</div>
);
}
}
ReactDOM.render(
<LikeButton />,
document.getElementById('example')
);
In ES6, derived classes have to call super() if they have a constructor. In react, all components extend from the Component class.
You don't actually need a constructor for every ES6/react class. If no custom constructor is defined, it will use the default constructor. For base classes, it is:
constructor() {}
And for derived classes, the default constructor is:
constructor(...args) {
super(...args);
}
You also need to call super() before accessing this, since this is not initialized until super() is called.
There are a few reasons to use a custom constructor in react. One is that you can set the initial state within the constructor using this.state = ... instead of using the getInitialState lifecycle method.
You can also bind class methods inside the constructor with this.someClassMethod = this.someClassMethod.bind(this). It's actually better to bind methods in the constructor since they will only be created once. Otherwise if you call bind or use arrow functions to bind methods anywhere outside the constructor (like in the render method), it will actually end up creating a new instance of the function on every render. Read more about that here.
If you want to use this.props in the constructor, you need to call super with props as an argument:
constructor(props) {
super(props);
this.state = {count: props.initialCount};
}
If you don't, then this.props is undefined in the constructor. However, you can still access this.props anywhere else in the class outside the constructor without needing to do anything with it in the constructor.
The super keyword in JavaScript is used in order to call the methods of the parent class. By itself, super() is used within a constructor function to call the parent constructor function. For example:
class Animal {
constructor(age) {
console.log('Animal being made');
this.age = age;
}
returnAge() {
return this.age;
}
}
class Dog extends Animal {
constructor (age){
super(age);
}
logAgeDog () {
console.log(`This dog is: ${ super.returnAge()} years old`);
}
}
const dog = new Dog(5);
console.log(dog);
dog.logAgeDog();
In this example we have a Dog class which extends an Animal class. The Dog class uses the super keyword twice. The first occurence is in the constructor, when super() is used in the constructor it will call the parent class constructor. Therefore we have to give the age property as an argument to it. Now the Dog successfully has an age property.
We can also use super outside of the constructor in order to access the parent's 'class' (i.e. prototype) properties and methods. We use this in the logAgeDog function located in the Dog class. We use the following code:
super.returnAge();
You should read this as:
Animal.returnAge(); // superClass.returnAge()
Why do I need this in React?
You need the super() keyword in React only when implementing a constructor. You have to do the following:
constructor(props) {
super(props);
// Don't call this.setState() here!
}
the parent class which is named Component needs to do some initialization on its own in order for React to work fine. If you implement a constructor without a super(props) call this.props in Component will be undefined which can lead to bugs.
I always write React code, particularly in ES6 Classes. But my question is, when do we use constructor(props) in React Components? Does the constructor(props) line has something to do with the rendering of the component together with its props?
The accepted answer is incorrect (perhaps just a misuse of the word "render").
As I explain in my comment on it the constructor of a React component is executed once the first time the component is mounted, or instantiated. It is never called again in subsequent renders.
Typically the constructor is used to set-up a component's internal state, for example:
constructor () {
super()
this.state = {
// internal state
}
}
Or if you have the class property syntax available (e.g. via Babel) you can forgo declaring a constructor if all you are using it for is to initialise the state:
class Example extends React.Component {
state = {
// internal state
}
}
Does the constructor(props) line has something to do with the rendering of the component together with its props?
The constructor does not directly dictate what is rendered by a component.
What is rendered by a component is defined by the return value of its render method.