Front-End Insights

A few words about ReactJS components


At the end of December I shared my early thoughts on ReactJS. Now it’s a few weeks later and I have some additional insights (more precisely about ReactJS components)… I hope you are not bored with all this ReactJS stuff yet 🙂

What my first problem with ReactJS components was

Well… last time I was basically excited about the idea of components:

It is not only the V from the MVC pattern. The component class is more like V(iew) and C(ontroller) together. It is very clear to me how to achieve a separation of concerns using these components.

But as I thought more about it, I had more and more doubts… From the very beginning of my “career” I was taught that separation of concerns means that every class should have only one responsibility. But let’s look at a typical ReactJS component class:

import Component from 'react-pure-render/component';
import React, { PropTypes } from 'react';
import Waypoint from 'react-waypoint';
import classNames from 'classnames';

import './FadeInDown.styl';

class FadeInDown extends Component {
  static propTypes = {
    children: PropTypes.element.isRequired,
    className: PropTypes.string,
    delay: PropTypes.number.isRequired

  constructor(props) {
    this.state = { wayPointEntered: false };

  onWayPointEnter() {
    const { delay } = this.props;

    this.setTimeoutId = setTimeout(() => {
        wayPointEntered: true
    }, delay);

  componentWillUnmount() {
    if (this.setTimeoutId) {

  render() {
    const { children, className } = this.props;

    const containerClasses = classNames({
      'fade-in-down': true,
      'visible': this.state.wayPointEntered,
      'invisible': !this.state.wayPointEntered

    return (
      &lt;div className={<code>${className} ${containerClasses}</code>}&gt;
        &lt;Waypoint onEnter={this.onWayPointEnter.bind(this)} /&gt;

export default FadeInDown;

The thing I don’t like in the component above is that we have the view template mixed with the component’s logic. I’ve always really liked to split these two chunks into separate files to keep the code structure clean and concise for me.

On the other hand…

…there is always a different point of view. A component may be treated as a chunk with only one purpose – this way we can say that ReactJS components fulfill the single responsibility principle.

I can even accept this way of thinking about ReactJS components, but then I see a problem with components which contain huge logic. I’ve read some articles about ReactJS where authors advise to split a component into smaller parts if it grows too heavily. Actually the split may usually be done by cutting html elements from the view along with a part of the logic which is related to it. However, if we look at the example above, we notice that it is long on the logic and short on the view – there is no chance to extract smaller components from it… That’s why in bigger projects, in my opinion, we can’t avoid situations where we end up with components with a huge logic and a small view. This reminds me of all those complaints about AngularJS and its many lined controllers (which can actually be avoided most of the time by using suitable directives).

I think that the growing of a component’s logic may be caused by the lack of a two way binding. In ReactJS you have to implement changes of the component’s state as well as the way the view should look depending on its state. Perhaps this results in components needing more code than would be required in other frameworks to achieve the same result.


I have been complaining a little bit today but don’t get me wrong – I know that ReactJS components have many advantages and are extremely efficient in rendering. However, I see a handful of gotchas here and I’m wondering what you think about the two I mentioned today?

  • Martin Schayna

    Well, that’s why Redux or other similar projects should be used in a huge application, logic is separated and components are connected to handle changes in the model.

    • Of course, Flux architecture may help you to separate part of the logic (related to the state of the whole app) but components will still have their own logic related to its own state…

      • Martin Schayna

        Sure, but state in compinents should be minimized as much as possible, see the difference in Redux “connected” and “dumb” components, the state is in the store and it is passed to components via props only. Need of render should be highly optimized via pure render and Reselect.

        • Yes, the state is in store, however it’s only application state (I hope you do it this way) – components may have its own state used for UI manipulations etc., so they have still its own logic inside which will likely grow in bigger apps…