Discover Functional JavaScript was named one of the best new Functional Programming books by BookAuthority!

Splitting a Single Page Application into layers has a set of advantages:

  • a better separation of concerns
  • the layer implementation can be replaced
  • the UI layer can be hard to test. By moving the logic to other layers, it becomes easier to test.

Below we can see the diagram of an application split in the three main layers:

  • UI (aka Presentation, View)
  • Domain (aka Business)
  • Data Access
R9TvA7YLrnFcjcKJML6qZQ1Ovuv19SSqeYSZ
Application Layers

The showcase

I’ll take the case of an application managing a list of to-dos. The user is able to see and search for to-dos.

Check the full implementation on git-hub.

IZH5sOtfQIydXXvMK0Cv0B1gD4-esCk6ztSe

UI Layer

The UI layer is responsible for displaying data on the page, and for handling user interactions. The UI Layer is made up of components.

I split the page in the following components:

  • TodoContainer manages the communication between TodoSearch, TodoList and other external objects
  • TodoSearchForm is the form for searching to-dos
  • TodoList displays the list of to-dos
  • TodoListItem: displays a single to-do in the list
NzfTbD-ZNPr8WPjOBJ40Mv2ATkO7iipike3f
Components Tree

TodoSearch

The component uses the handleChange handler to read the input value on any change. TodoSearch exposes a new property: onSearch . It can be used by the parent component to handle the search click.

The component doesn't communicate with any other external objects, except its parent. TodoSearch is a presentation component.

export default class TodoSearch extends React.Component { 
  constructor(props){
    super(props);
    this.search = this.search.bind(this);
    this.handleChange = this.handleChange.bind(this);

    this.state = { text: "" };
  }
  
  search(){
    const query = Object.freeze({ text: this.state.text });
    if(this.props.onSearch)
      this.props.onSearch(query);
  }
  
  handleChange(event) {
    this.setState({text: event.target.value});
  }
  
  render() {
    return <form>
      <input onChange={this.handleChange} value={this.state.text} />
      <button onClick={this.search} type="button">Search</button>
    </form>;
  }
}

TodoList

TodoList gets the list of todos to render using a property. It sends the todos, one by one, to the TodoListItem.

TodoList is a stateless functional component.

export default function TodoList(props) {
  function renderTodoItem(todo){
    return <TodoListItem todo={todo} key={todo.id}></TodoListItem>;
  }

  return <div className="todo-list">
      <ul>
        { props.todos.map(renderTodoItem) }
      </ul>
    </div>;
}

TodoListItem

TodoListItem displays the todo received as a parameter. It is implemented as a stateless functional component.

export default function TodoListItem(props){
  return       <li>
    <div>{ props.todo.title}</div>
    <div>{ props.todo.userName }</div>
  </li>;
}

Read Functional Architecture with React and Redux and learn how to build apps in function style.

Discover Functional JavaScript was named one of the best new Functional Programming books by BookAuthority!

For more on applying functional programming techniques in React take a look at Functional React.

You can find me on Medium and Twitter.