We use cookies and other tracking technologies to improve your browsing experience on our site, analyze site traffic, and understand where our audience is coming from. To find out more, please read our privacy policy.

By choosing 'I Accept', you consent to our use of cookies and other tracking technologies.

We use cookies and other tracking technologies to improve your browsing experience on our site, analyze site traffic, and understand where our audience is coming from. To find out more, please read our privacy policy.

By choosing 'I Accept', you consent to our use of cookies and other tracking technologies. Less

We use cookies and other tracking technologies... More

Login or register
to apply for this job!

Login or register to start contributing with an article!

Login or register
to see more jobs from this company!

Login or register
to boost this post!

Show some love to the author of this blog by giving their post some rocket fuel 🚀.

Login or register to search for your ideal job!

Login or register to start working on this issue!

Engineers who find a new job through JavaScript Works average a 15% increase in salary 🚀

Blog hero image

React: Class Component vs Stateless Component?

Ven Korolyov 15 March, 2018 | 4 min read

Most new react developers ask these two questions: what is the difference, and which one should I use? In this article, we will try to understand the basic difference between component class, and stateless component, and which one you should use. Let’s start.

First of all, we need to understand what are these two components:

A stateless component is just a plain javascript function which takes props as an argument and returns a react element.

MyStatelessComponent = props => <div>{props.name}</div>;
// without JSX
const MyStatelessComponent = props => React.createElement('div', null, props.name);

A stateless component has no state(obvious, isn’t it?), it means that you can’t reach this.state inside it. It also has no lifecycle so you can’t use componentDidMount and other hooks.

When I said that it should return a react element it might not have been clear for you. React element is an object which has 2 properties(actually more but we’re interested in only 2 props now): type(string), props(object). Our stateless component’s element would look like this:

   type: 'div',
   props: {
     children: props.name,
   }
}

When react renders our stateless component all it needs to do is call MyStatelessComponent function and pass props there. That’s it.

Component class is a bit more complicated. It has a state, lifecycle hooks and it is a javascript class which means that React creates instances of it. React should initialise the component class in order to call lifecycle hooks, call a constructor, initialise state and more.

MyComponentClass extends React.Component {
  render() {
    return <div>{this.props.name}</div>;
  }
}

This is how our stateless component would look like if it was written as a component class. React expects it to return a react element from its render function. If we compare what render function returns and what returns the stateless component function we will see that those two elements are identical.

Now that we know the difference, which one should we use?

We know that it takes more time to create an instance of a class rather than calling a function, right? What if we render 10000 elements of stateless components and class components? Which one would be faster? I was surprised because there is no difference in render time between those two renders. Actually, there is, but it is insignificant and always different.

blog1.jpeg

It is not that much faster, but there is another difference — the amount of code. If for a stateless component code looks like this after turning it to ES5 (using https://babeljs.io/repl/):

MyStatelessComponent = function MyStatelessComponent(props) {
  return React.createElement(
    "div",
    null,
    props.name
  );
}

A component class would look this:

_createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var MyComponentClass = function (_React$Component) {
  _inherits(MyComponentClass, _React$Component);
function MyComponentClass() {
    _classCallCheck(this, MyComponentClass);
return _possibleConstructorReturn(this, (MyComponentClass.__proto__ || Object.getPrototypeOf(MyComponentClass)).apply(this, arguments));
  }
_createClass(MyComponentClass, [{
    key: "render",
    value: function render() {
      return React.createElement(
        "div",
        null,
        this.props.name
      );
    }
  }]);
return MyComponentClass;
}(React.Component);

The difference is pretty big, isn’t it? Of course, it will be minified after running it through any builder (webpack, gulp, grunt) but even then the difference is still large: 1.2kb against 97 bytes.

Now we know differences in terms of performance but are there any other difference we need to know? Why are there two of React component types instead of one? Let’s try to answer this question now:

When should you use a stateless component?

A stateless component(or dumb) is just presentation of the state(props). It only can render props and it should only do that. A good example is a button component: let’s say we have a button which needs to be styled especially so we create a button stateless component which would look like this:

Button = props => (
   <button className="our_button" onClick={props.onClick}>
      {props.label}
   </button>
);

You don’t need to have a state, lifecycle hooks or any internal variables inside a button component, you just simply need to render that.

When should you use a class component?

A class component should be used whenever you need to work with state, it might be redux, relay or internal react state. Whenever you need to fetch data before you render you component you should call a fetchData function in componentDidMount to be sure that your data will be fetched as soon as possible. You can’t use any side-effect inside render function so that’s why you should do side-effects inside lifecycle hooks. So the rule would be: if your component needs some data which cannot be passed as a prop use class component to get that data. If you need to keep UI state in your component(expandable blocks) so it’s a good place to keep that info in a components state.

Conclusion. Now we know what the differences are, and which one we should use in any particular case. Hope you enjoyed!

Originally published on itnext.io

Related Jobs

Related Issues

viebel / klipse-clj
viebel / klipse-clj
  • Open
  • 0
  • 0
  • Intermediate
  • Clojure
viebel / klipse
  • Open
  • 0
  • 0
  • Intermediate
  • Clojure
viebel / klipse
  • 1
  • 0
  • Intermediate
  • Clojure
viebel / klipse
  • Open
  • 0
  • 0
  • Intermediate
  • Clojure
  • $80
viebel / klipse
  • Open
  • 0
  • 0
  • Advanced
  • Clojure
  • $80
viebel / klipse
  • Started
  • 0
  • 2
  • Advanced
  • Clojure
  • $180
viebel / klipse
  • Started
  • 0
  • 1
  • Intermediate
  • Clojure
viebel / klipse
  • Started
  • 0
  • 3
  • Intermediate
  • Clojure
  • $80
viebel / klipse
  • 1
  • 0
  • Advanced
  • Clojure
  • $300

Get hired!

Sign up now and apply for roles at companies that interest you.

Engineers who find a new job through JavaScript Works average a 15% increase in salary.

Start with GithubStart with Stack OverflowStart with Email