React Component vs Stateless Functional Components

Asked

Viewed 657 times

7

I know that in React there are two types of declaration for a component.

React Component

export default class App extends Component {
  render() {
    return (
      <Elemento/>
    );
  }
}

React Stateless Functional Components

const App = () => (
  return <Elemento/>
);

The React Component allows the use of states and this is a difference between the statements. However, I have some doubts:

  • There are extra differences (apart from the state issue) between the use of statements?
  • Use the stateless Components when no state needs will bring a better performance?
  • What are the main advantages of stateless Components in relation to the normal declaration?

1 answer

8


There are extra differences (apart from the state issue) between the use of statements?

Yes and no. It is possible, at least in theory, to accomplish everything you would do with stateless Components with class Components (the contrary is not true, more about it in the sequence), but the approach should be according to the goal you want to achieve. There are cases where the use of stateless Components is most suitable for the simple fact that the state is not necessary (as the name already implies).

Stateless Components are, in a simplistic way, the representation of a state passed to a method of surrender via props. A button component would be a good example:

const Button = props => (
   <button className={props.className}>
      {props.label}
   </button>
);

This component has the sole purpose of rendering props, and that’s the only thing he should do. These props may come from a state (or anything else) of a higher component in the chain, but from the point of view of the encapsulated component, the state does not exist and is therefore immutable. This also represents a bit of functional nature that can be achieved with React, using some concepts from Functional Programming. Without going into too much detail, pure functions are those whose result is always the same, given the same set of initial data. It can be understood that the function Button that I created is therefore pure. The return, in this particular case, is a JSX element.

Yet, stateless Components do not allow access to life cycle of React and Hooks, as componentDidMount() and the like, which is already possible to do with class components. It is common to search data in an API, for example, using the componentDidMount(), or destroy objects and displace resources in componentWillUnmount(). This is only possible in components written in class form

export default class App extends Component {

  constructor(props) {
    super(props);
    // Code ...
  }

  componentDidMount() {
    // Code ...
  }

  componentWillUnmount() {
    // Code ...
  }

  render() {
    return (
      // Code ...
    )
  }
}

That is, from a theoretical point of view, each of the statements has a very specific use. From a practical point of view, it is possible to do everything with class-shaped components, but it is not always worth it. Which brings us to the next question:

Using stateless Components when you don’t need status will bring a better performance?

This guy made the test. It urged several functional components and several class components and measured the time to render of each one of them. At the end of the day, the performance difference is negligible. But there is a fundamental difference between them which is the code transposed for ES5. See the difference of a transpylated functional component

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

For a class component, after the same process:

var _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);

Thinking of an application that has a large number of components, this code can potentially be generated for each of them, generating an extremely large production Javascript. Which means that

What are the main advantages of stateless Components compared to normal statement?

From ready hit, a palpable advantage is the generated code to be smaller. Another advantage is that functional programming (i.e., stateless Function Components) is less error prone, then you may end up generating a more solid code base in the case of components where the state is not important. A HOC to work with the time of loading of components, for example, can be easily created functionally and is much easier to maintain. Another point is the separation of responsibilities. If you don’t need the state, use something that gives you just that, avoiding the Overkill.

If the only tool we know is a hammer, everything will look like a nail. Starting from this maxim, it is good to know the whole Toolset and know when to use what.

Conclusion: A functional component has no status, no access to life cycle methods and is easier to write since it is a function. (Trivia: it is possible to create functional components as methods of a class representing a class component. It opens possibilities for several things). A class component has been and allows access to life cycle methods. If you need to keep the state of the UI encapsulated in the component, the solution with classes is the most suitable. Remember that the React will instantiate an object every time the render occurs, which can lead, in extreme cases, to memory problems. So if you detect components that can be written as functional, write them.

  • 2

    Show Caio! Very good reply! Thanks for sharing!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.