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
Related
I am reviewing some React Js basics and I need some clarifications about the use of the constructor method within a react class based component. My normal practice is to declare a class based component and define state without using the constructor, like so:
import React, { Component } from 'react';
export class Testing extends Component {
state = {
example: "Hello World!!!"
}
render() {
return <div>
{this.state.example}
</div>;
}
}
export default Testing;
Since state is so easy to use without the (seemingly) pointless constructor, I began asking myself what the constructor was for. Just to clarify what I mean by the constructor, it is when you declare state like this instead of the above example:
constructor(props) {
super(props)
this.state = {
example: "Hello World!!!"
}
}
I found the suggestion in the react documentation that it is best practice to utilize the constructor, but it did not say why. After a little searching, I found a source that suggested that the constructor give you access to the props. I tested this and do see how the constructor gives access to props; however, the class can access props WITHOUT using the constructor, simply by stating this.props.myTest. I tested this as well by defining props in a parent component and drilling them down to the child component. I was able to access the props just fine with the this.props.myTest statement, no constructor necessary. So my question is, "What specifically does the constructor do, and when is it necessary (or is it ever necessary)?"
"when is the constructor necessary ?":
The constructor is not necessary, if you don't need it.
You might need a constructor e.g. if you need to bind a method to the class instance (so that this keeps pointing to the
class instance if you pass the function over to some other execution context):
export class Testing extends Component {
constructor( props ) {
super( props );
this.myMethod = this.myMethod.bind( this );
}
myMethod(){
console.log( this.props );
}
render() {
return <button onClick={ this.myMethod }>
click
</button>;
}
}
"What specifically does the constructor do" ?
A constructor "creates the instance" in javascript. So without a constructor, there would be no instance.
But also there is inherently always a constructor, even if you don't define one specifically.
You can define a constructor to overwrite the default constructor or to add some extra logic to be run
additionally to the super-constructor.
Accessing this.props in React
In javascript you could not access this.props without calling super(props).
Note that the constructor argument props and the instance property this.props are different "things".
Let's rename the constructor argument for now, to make it more obvious:
class SuperClass {
constructor( constructorArguments ) {
this.props = constructorArguments;
}
}
class DerivedClass extends SuperClass {
constructor( props ) {
super(); // <-- call the SuperClass constructor
}
method(){
console.log( this.props ); // <-- this.props is obviously never defined
}
}
const instance = new DerivedClass('some props');
instance.method();
But React "takes measures" to assign this.props anyway,
even when super(props) was never called.
But that happens later (after the constructor is done),
so you are able to access this.props in other methods later, but not inside the constructor:
export class Testing extends Component {
constructor( constructorArguments ) {
super(); // <-- super() is called without arguments
console.log( this.props ); // <-- this.props is undefined
}
render() {
console.log( this.props ); // <-- React sorted it out, now this.props is available
return null;
}
}
If you pass the constructor arguments to the super class constructor, then you can access this.props
inside the constructor:
constructor( constructorArguments ) {
super( constructorArguments ); // <-- super() is called with arguments
console.log( this.props ); // <-- this.props is available
}
React recommends to call super(props) anyway, to avoid introducing bugs with later changes.
I might add that it is very little extra code that doesn't do any harm.
Defining the state
class fields were not always available, so you had to define the state inside
the constructor, as the React example shows (like this.state = { value: 'value' }).
I personally think that it is probably ok now to use the class fields, but I always
tend to follow the official documentation, even if it might be outdated. There still
might be implications which I am not aware of.
See also: is-it-better-to-define-state-in-constructor-or-using-property-initializers
I mostly see JavaScript use classes as a constructor as following:
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
// Getter
get area() {
return this.calcArea();
}
// Method
calcArea() {
return this.height * this.width;
}
}
What's the reason React uses classes without using the contructor() function, such as following? I don't see classes being used to create instances.
class App extends Component {
render() {
return (
<div className="app-content">
</div>
)
}
}
Right now you should use classes in React if you need to use "advanced" component lifecycle methods like shouldComponentUpdate() or such.
Previously class components were used to handle local state in them. Right now we have Hooks API which allows to use state in a more elegant way and without need of class components.
If you want more details, you can read the article by Dan Abramov: How Are Function Components Different from Classes?.
Regardless your example, you're right, this code:
class App extends Component {
render() {
return (
<div className="app-content">
</div>
)
}
}
can be written as:
function App() {
return <div className="app-content"></div>
}
What's the reason React uses classes without using the contructor() function
From the JavaScript class doc:
If you do not specify a constructor method, a default constructor is used.
So a constructor exists for every class whether a constructor method is specified or not.
I don't see classes being used to create instances.
React components implemented as classes get instantiated by React as part of the rendering process.
Specifically, in the new React Fiber creating an instance of a React class component happens on this line of the source code.
But yes, #vicondin is right that the simple component from the question can be implemented as a function component, that class components used to be the only way to maintain state, implement lifecycle methods, etc., and that the new Hooks makes it possible to...
use state and other React features without writing a class.
In React, state is used in a React class component. There you can set initial state in the constructor of the class, but also access and update it with this.state and this.setState, because you have access to the class instance by using the this object.
If you use class in React component, even without using constructor() you can set initial state like below:
class App extends Component {
state = {
hello: 'Hello'
};
onClickHello = value => {
this.setState({ hello: 'Why did you clicked?' });
};
render() {
return (
<div className="app-content" onClick={this.onClickHello}>
{this.state.hello}
</div>
)
}
}
Another advantage is you can make use of all the React lifecycle methods
Update: After React16, you can use the lifecycle events even in function components using react hooks
Also biggest reason is the handling of state and lifecycle(componendDidMount ..etc) , class can do everything functions can , but at the cost of readability and statelessness . But in the most cases I rarely use classes only if I need a complex parent component with lifecycle
In React's source code, the prototype function has a signature with three parameters:
function Component(props, context, updater) {
But everytime I see somebody extends React.Component using modern ES6 features, they declare constructor with only props as follows:
constructor(props)
What is the difference between a prototype function and constructor literal? And where do the rest two arguments go?
You can obviously use all of the three params provided in the Component. But in general, only in an advanced case we use props, not every time. Similarly, you can use others.
Here's an example with context api:
ES6 class component
class ContextConsumer extends React.Component {
/*
contexTypes is a required static property to declare
what you want from the context
*/
static contextTypes = {
currentUser: React.PropTypes.object
};
render() {
const {currentUser} = this.context;
return <div>{currentUser.name}</div>;
}
}
ES6 class component with an overwritten constructor
class ContextConsumer extends React.Component {
static contextTypes = {
currentUser: React.PropTypes.object
};
constructor(props, context) {
super(props, context);
...
}
render() {
const {currentUser} = this.context;
return <div>{currentUser.name}</div>;
}
}
Example taken from this blog. I will suggest you to look into the blog to be more familiar with it.
Another param is updater which you may have used this.forceUpdate() and doing so invoke the updater. But the fact, we do not use updater directly in normal case. Though, I have not faced such case to use the updater inside the constructor. You might be able to figure out if you face some advanced case.
To be more frank and to use react with clever, I never even try to use props as far as possible. They are just provided for us so that we can utilize in lifecycle hooks when needed.
Okay, let me explain it a little bit with react code:
function Component(props, context, updater) {
this.props = props;
this.context = context;
// If a component has string refs, we will assign a different object later.
this.refs = emptyObject;
// We initialize the default updater but the real one gets injected by the
// renderer.
this.updater = updater || ReactNoopUpdateQueue;
}
Component.prototype.forceUpdate = function(callback) {
this.updater.enqueueForceUpdate(this, callback, 'forceUpdate');
};
The Component function has 3 arguments which is being utilized inside the function. Later, its prototype forceUpdate is defined on which the updater is being hooked to enqueue the forceUpdate with enqueueForceUpdate. So, this.forceUpdate actually calling the Component updater and allows us to re-render the component. I hope, looking at its prototype method makes sense now.
What is the difference between a prototype function and constructor literal?
As far as I understand, you wanted to know why constructor is being called with the desired params.
The class/function constructor is used so that you can use an override to the function. For eg, passing props inside the constructor, you wanted to do an override with this. So, you explicitly notify the function to use the props as used inside the constructor.
So Es6 added the class keyword along with the constructor for it. It is however just syntactic sugar and is still based on the prototype model as before.
I don't know about the other two argos but I would guess it has to do with the function creating its own lexical scope.
I want to know the conditions where by a constructor is not needed in a component's class declaration. I figure it is for stateless components, but are there any other reasons? Would not having any functions inside the component (besides life cycle functions) be one, for example?
I think it would be appropriate to just leave here an excerpt from react docs (emphasis mine):
The constructor is the right place to initialize state. If you don't
initialize state and you don't bind methods, you don't need to
implement a constructor for your React component.
I usually only add a constructor if the component has a internal state I need to set up before it is used, otherwise I leave out the constructor. Having functions in the component doesn't affect my decision in this regard
You don't actually need a constructor at all in any case if you use the babel stage-2 preset, because it provides the class properties that effectively replace its usage:
class Component extends React.Component {
constructor() {
this.state = {};
this.handleClick = this.handleClick.bind(this);
}
handleClick() { console.log('click'); }
}
becomes
class Component extends React.Component {
state = {};
handleClick = () => console.log('click');
}
Ignoring this, a constructor is needed only if you need to bind component methods to its context, or if you need to initialize the state property.
Another case is if you need to do something with the this.props class property, but this is considered an anti-pattern by React.
class Component extends React.Component {
constructor() {
this.state = {
// don't do this! anti-pattern! duplication of source of truth!
duplicatedState: this.props.myName,
};
}
}
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.