liveBook · Manning

Pure function

As explained in Build a Frontend Web Framework (From Scratch)

A function that produces the same output for the same inputs and has no observable side effects.

A pure function returns the same result for the same arguments and has no side effects. It does not change something outside its scope. This makes it useful for describing a view: pass in application state, get back a virtual DOM tree, and leave changes to the real DOM to the framework. section 3.8.2 section 9.1

A simple stateless component has two jobs:

  • Receive the state it needs as an argument. Data passed into a component from outside is called props. section 3.8.1 section 3.8.3
  • Return virtual DOM for its part of the view. It does not manipulate the browser’s DOM itself. section 3.8.2 section 3.9

A list from an argument

`TodosList(todos)` maps each to-do to a virtual `li` and returns a virtual `ul`. Calling it with `['Walk the dog', 'Water the plants']` describes a two-item list; the framework renders that description as HTML. The function describes what to show, rather than inserting list items into the document. section 3.8.2

function TodosList(todos) {
  return h('ul', {}, todos.map((todo) => h('li', {}, [todo])))
}

The listing shows the small JavaScript function that turns a to-do array into virtual DOM. section 3.8.2

Pure view functions can call other pure view functions. Instead of one long function for an entire to-do application, an `App(state)` function can combine a heading, a creation form, and a to-do list. The list can then call a function for each item. Each function receives the relevant data and returns its piece of the virtual DOM. section 3.8.3

function App(state) {
  return hFragment([
    h('h1', {}, ['My TODOs']),
    CreateTodo(state),
    TodoList(state)
  ])
}

The listing shows a parent view function composing smaller components without creating a parent HTML element. section 3.8.3

Purity also matters when updating state. A reducer takes the current state and action data and returns a new state object. It must not mutate its arguments or produce side effects. For example, an add-to-do reducer builds a new to-do array from the old one and the current input, then clears the input in the returned state. section 6.3.2

'add-todo': (state) => ({
  ...state,
  currentTodo: '',
  todos: [...state.todos, state.currentTodo],
})

The reducer listing shows a new state object and array being returned instead of changes to the existing ones. section 6.3.2

A pure function cannot maintain a component’s own state: its output depends only on its arguments. A stateful component therefore needs a different arrangement. In the class-based approach, instances hold state and have a lifecycle. A React function using `useState()` is not pure either; the hook stores state outside the function’s scope. For a first stateless view, passing in the application state is enough. section 9.1 section 3.8.1

How Build a Frontend Web Framework (From Scratch) covers it

How deep it goes
Defines determinism and side effects, then demonstrates view composition and immutable reducer updates; component-held state is treated separately.
Examples
Shows a to-do list view, a composed application view, and an add-to-do reducer.
What it assumes
Assumes basic JavaScript functions, arguments, objects, and arrays; defines purity and props where they become relevant.
What you can do after
Build it from scratch as JavaScript view functions and reducers that return results without changing their inputs.
How it connects
Connects pure functions to stateless components, props, virtual DOM, reducers, and stateful components.

Also explained in

Compare how 19 books explain pure function →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Build a Frontend Web Framework (From Scratch). The section links point to the parts of the book it draws on.