Reputation: 11830
I started learning React when we could simply use state and create object instead of using constructor(props){ super(props)
Now, I see many libraries where they are still using
class Master extends Component {
constructor(props){
super(props)
So my first question is if there is an advantage of using constructor (props) super(props)
and then setting up state? instead of just creating state object?
Second question, I wanted to implement react-native-slowlog in the native app I am making.
Throughout the code I have created the state object
directly instead of using constructor.
The documentation for the react-native-slowlog shows this way to use it
class Master extends Component {
constructor(props){
super(props)
slowlog(this, /.*/)
this.state = this.getDataSource(props)
this.shouldComponentUpdate = shouldComponentUpdate.bind(this)
}
...
}
Where they call slowlog(this, /.*/)
inside the constructor, so my question is can I avoid using constructor here? or is it okay if I create a constructor where I do slowlog(this, /.*/)
and then create state object outside the constructor?
class Master extends Component {
constructor(){
super()
slowlog(this, /.*/)
}
state = {
searchCoin: false
}
Upvotes: 4
Views: 1767
Reputation: 2638
You only need to use the constructor if you are initializing state or binding functions.
If you don’t initialize state and you don’t bind methods, you don’t need to implement a constructor for your React component. https://reactjs.org/docs/react-component.html#constructor
So for what the library you linked to does, you do need to call it in the constructor. It both initializes the state and binds to the shouldComponentUpdate function.
However, if you aren't binding to anything you could always initialize the state directly on the property like this...
Typescript
class Master extends React.Component<any, any> {
public readonly state = { someKey: "Initial Value" };
}
Javascript
class Master extends React.Component {
state = { someKey: "Initial Value" };
}
Also I am not sure what the this.getDataSource(props)
function does, and if that is just the example provided by slowlog. But initializing the state on the class property AND from the constructor won't wont. So you can do it like your example showed OR you could call that function from the componentDidMount function.
class Master extends React.Component {
// initialize your state
state = { someKey: "Initial Value" };
constructor (props) {
super(props)
slowlog(this /*, */);
this.shouldComponentUpdate = shouldComponentUpdate.bind(this);
}
componentDidMount() {
const nextState = this.getDataSource(this.props);
this.setState(nextState);
}
}
On thing to note is that if getDataSource
returns a promise, that should be called when the component mounts, rather than from the constructor.
If you need to load data from a remote endpoint, this is a good place to instantiate the network request. https://reactjs.org/docs/react-component.html#componentdidmount
Upvotes: 1
Reputation: 9671
constructor (props){}
and super(props)
?The only reason is when you want to access this
inside of the constructor React source code
if you pass:
class MyComponent extends React.Component {
constructor(props) {
super(props)
console.log(this.props)
// goood
}
}
if you are not passing but call super
class MyComponent extends React.Component {
constructor(props) {
super()
console.log(this.props)
// -> undefined
// Props parameter is still available
console.log(props)
// good
}
render() {
// No difference outside constructor
console.log(this.props)
// good
}
}
if you dont call
class MyComponent extends React.Component {
constructor(props) {
console.log(this)
// undefined
}
}
So in summary that is not always needed.
That is just syntax sugar, therefore no difference.
constructor only get calls once per mount, so you want to do stuffs that you don't want to do on every render.
Upvotes: 5
Reputation: 222369
It's possible to skip explicit constructor
if state
is all you need to define, because this can be done with class fields proposal:
class Master extends Component {
state = { searchCoin: false };
...
Which is syntactic sugar for ES6:
class Master extends Component {
constructor(props){
super(props);
this.state = { searchCoin: false };
}
...
This is a matter of taste whether state
is defined as class field or as a part of constructor
body if there's a need for constructor
; class field takes less characters to type because it doesn't contain this.
Also notice that
class Master extends Component {
constructor(){
super()
slowlog(this, /.*/)
}
state = { searchCoin: false }
...
is syntactic sugar for
class Master extends Component {
constructor(){
super()
this.state = { searchCoin: false };
slowlog(this, /.*/)
}
...
Class fields go after super
and before other constructor statements. This may not work as intended if slowlog
is expected to run first.
Upvotes: 3