I am learning Reactjs, I am trying to write a basic component, can anyone tell me why this component syntax:
import React, { Component } from 'react';
export default class AboutPage extends Component {
render: function() {
const { page } = this.props;
return (
<div className="blog-post">
<h2 className="blog-post-title">{page.title.rendered}</h2>
<div dangerouslySetInnerHTML={this.createMarkup(page.content.rendered)} />
</div>
);
}
}
Is different to this component?
var HelloMessage = React.createClass({
render: function() {
return <div>Hello {this.props.name}</div>;
}
});
Why use export default class
instead of just var HelloMessage = React.createClass({
?
The createClass
syntax was the original way to create React components, but it seems like it's being phased out in favour of the class
syntax and stateless functional components.
There are a few key differences to be aware of if you're upgrading a component from createClass
a class
.
With createClass
you could declare methods that would return the initial state and default properties for a given component.
React.createClass({
getInitialState() {
return { foo: 'bar' };
},
getDefaultProps() {
return { baz: 'qux' };
},
componentDidMount() {
console.log(
this.state, // => { foo: 'bar' }
this.props // => { baz: 'qux' }
);
}
});
Both have been changed for the class syntax. Instead, you assign your initial state inside the constructor.
class extends React.Component {
constructor() {
super();
this.state = { foo: 'bar' };
}
}
And you declare the default props as a static property.
class Qux extends React.Component {}
Qux.defaultProps = { baz: 'qux' };
The createClass
syntax supports a concept called mixins, which allow you to provide other code which augments the existing lifecycle methods.
const logOnMount = {
componentWillMount() {
console.log('Mounted!', new Date());
}
};
React.createClass({
mixins: [logOnMount]
});
Any component using the logOnMount
mixin will log a timestamp to the console whenever it is mounted.
There's no support for mixins with the class
syntax, but you can use higher-order components to achieve the same things.
function logOnMount(Component) {
return function(props) {
console.log('Mounted!', new Date());
return (
<Component {...props} />
);
}
}
The createClass
syntax provided some handy auto-binding so that you could safely pass component methods as callbacks and not have to worry about ending up with the wrong context for this
.
React.createClass({
bar() {
return true;
},
foo() {
this.bar();
},
render() {
return <button onClick={this.foo}>Click</button>;
}
});
The onClick
handler will try and invoke this.foo
with this
set as the event that was triggered, but because this.foo
was autobound to have the correct context, there's no error.
Here's the same example, but with classes.
class extends React.Component {
bar() {
return true;
}
foo() {
this.bar(); // Error - undefined is not a function
}
render() {
return <button onClick={this.foo}>Click</button>;
}
}
The foo
method ends up with this
set to the event, which doesn't have a bar
property.
To get around this, you'll need to explicitly bind the methods in the constructor, or invoke the method from inside an arrow function.
constructor() {
this.foo = this.foo.bind(this);
}
// or
render() {
return <button onClick={e => this.foo()}>Click</button>;
}
First, there's also another option that you haven't mentioned:
export default function AboutPage(props) {
const { page } = props;
const pageContentMarkup = createMarkup(page.content.rendered);
return (
<div className="blog-post">
<h2 className="blog-post-title">{page.title.rendered}</h2>
<div dangerouslySetInnerHTML={pageContentMarkup} />
</div>
);
This one is very terse and emphasises that your component is stateless.
Secondly, the class syntax notably doesn't allow using mixins. Some say this is a feature, not a bug, and we should actually move away from mixins.
Dan Abramov makes an argument that mixins don't compose well, and proposes higher order components as an alternative. "Higher order component" is a fancy term for a function that takes a React component class and returns another class that some behaviour added. Higher order components can be seen as "decorators". You apply them in order to a component and they will each still do their own thing without even needing to know about each other.
This looks like a good reason to leave behind the old syntax and move forward with classes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With