liveBook · Manning

Component

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

A modular application unit that can load data, execute lifecycle logic, and produce part of a user interface.

A component owns a manageable part of an application's view. Instead of generating one large virtual DOM tree, split the view into smaller pieces that can be composed. Each piece is responsible for what its part displays and how users interact with it. section 3.7.2 section 3.8

Start simply: make each component a pure JavaScript function. Give it application state, or just the data it needs, and have it return a virtual DOM tree. Data passed into a component is called props. At this stage, components do not hold their own state or lifecycle. section 3.8.1 section 3.8.3

Split a to-do view

An App() function can return a fragment containing a heading, CreateTodo(state), and TodoList(state). TodoList() can map to-do data into TodoItem() calls. This keeps the form, list, and individual items in separate functions while producing one composed view. section 3.8.3

To handle interaction, pass an emit() function alongside state. A form component can display the current input value and emit an event when the user types; the application's reducer then updates state. Rendering that state updates the input, connecting the component to both the renderer and state manager. section 6.3.3

The fuller version gives each component instance its own state and lifecycle. A class supplies a render() method for its virtual DOM, plus mount() and unmount() methods to add and remove that view. A lifecycle hook can run code at a particular moment—for example, fetching data after mounting. Parent components can pass props to children, while children can communicate upward through events. section 1.2.2 section 9.2

Listing 9.1 Basic component methods (component.js)
import { destroyDOM } from './destroy-dom'
import { mountDOM } from './mount-dom'

export function defineComponent({ render }) {  #1
  class Component {  #2
    #vdom = null
    #hostEl = null

    render() {  #3
      return render()
    }

    mount(hostEl, index = null) {
      this.#vdom = this.render()  #4
      mountDOM(this.#vdom, hostEl, index)  #5

      this.#hostEl = hostEl
    }

    unmount() {
      destroyDOM(this.#vdom)  #6

      this.#vdom = null
      this.#hostEl = null
    }
  }

  return Component  #7
}

See how defineComponent() creates a class whose render(), mount(), and unmount() methods connect a component's virtual DOM to the browser DOM. section 9.2

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

How deep it goes
Builds from pure rendering functions toward component classes with render(), mount(), and unmount(); introduces independent state and lifecycle as later capabilities.
Examples
Uses a to-do application split into a form, list, and items, including input events and conditional item editing.
What it assumes
Starts with JavaScript functions and application state; introduces props and virtual DOM composition before adding component classes.
What you can do after
Build it from scratch as composable JavaScript rendering functions, then implement a basic class with rendering, mounting, and unmounting methods.
How it connects
Connects components to virtual DOM, props, application state, events, reducers, and lifecycle hooks.

Also explained in

Compare how 10 books explain component →

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.