Do you remember React and how deep in love I am?

Right then, today I come with modular components! Or as I call them to look fancy, smart components.

Smart, modular?

Well, a little disclaimer here: They're not named like that, nor is an official term, is something that I've made up.

But, what do I mean? Well, usually in react you will want to make either state components, and not rely on any storage managers (Like Redux), you would just create a plain component:

import React from 'react';

class MyComponent extends React.Component {
  constructor() {
    this.state = {
      value: 'World
    };
  }
  /* Render method */
  render() {
    return (
      <div>
        Hello {this.state.value}!
      </div>
    );
  }
}

Right? Well, and what if you don't want your component to handle the state? Just rely on an external state container:

import React from 'react';

export const MyComponent = ({ value = 'World' }) => (
  <div>
    Hello {value}!
  </div>
);

Fine, those are the typical methods you'll find around, internet is full of them. But those methods do not fit into the app that I'm working on right now.

The smart component

To keep things modular, and not rely on a single store I came up with an idea: Divide the component into three parts, in a similar fashion to Angular, Style, View and Controller.

Folder structure

Don't get me wrong, I'm not trying to mimic Angular, I like react how it is. But some times, you can mix the best (or simply what you like) from both worlds.

First layer: The style

Instead of relying in engines like Less, Sass or just CSS, I've implemented the styling using Emotion, a great framework to make styles inside code.

import styled from '@emotion/styled';

/**
 * Style container component.
 */
export const MyComponent = styled.div`
  /* Your styles go here */
`;

Second layer: The fragment

Then, you just move away the representational logic from the component itself, this part is just like delegating the render method to make your component more readable, but still, having a re-usable view component.

import React from 'react';
import * as style from './MyComponent.style';

/**
 * Component fragment.
 */
export const MyComponentFragment = ({ state }) => (
  <style.MyComponent>
    Some {state}
  </style.MyComponent>
);

Third layer: The controller

Finally, the last layer: The controller component. This one uses the fragment to represent the component, passing the state from itself to the fragment by it's props.

import React from 'react';
import { MyComponentFragment } from './MyComponentFragment';

export class MyComponent extends React.Component {
  constructor() {
    this.state = { value: 'Your state' };
  }
  render() {
    return React.createElement(MyComponentFragment, {
      value: this.state.value
    });
  }
}

Do you remember that I said that I didn't want to use state management libraries and stuff like that? Well, I lied. This is what you could call a design pattern, and in fact, it does not eliminate the use of things like Redux, it can be used along!

TL;DR

Okay, summarizing, what I'm presenting you is a simple design pattern that divides a component into three parts: Style, View and Controller.

  • Style: A styled component using Emotion js or similar.
  • Fragment: A stateless component that uses the style container.
  • Controller: A state component that uses the fragment in the render method.

In that way, you don't have everything in the same module or component, making the whole thing more maintainable plus you gain re-usability from each part.

Final words

This idea came to my mind when designing the structure of an app that I'm working on right now, it's a collaborative project with a friend of mine. More about the project will be leaked in the course of the following months!

Spoiler: It's about creating an IDE, but of what kind? You will see soon!