hyperapp/docs/api/h.md

7.6 KiB

h()

Definition:

A function that creates virtual DOM nodes (VNodes) which are used for defining views.

Import & Usage:

import { h } from "hyperapp"

// ...

h(tag, props, children)

Signature & Parameters:

h : (String, Object, VNode? | [...VNodes]?) -> VNode
Parameters Type Required?
tag String yes 💯
props Object yes 💯
children VNode or array of VNodes no
Return Value Type
virtual node VNode

h() effectively represents the page elements used in your app. Because it's just JavaScript we can easily render whichever elements we see fit in a dynamical manner.

const hobbit = (wearingElvenCloak) =>
  h("div", {}, [
    !wearingElvenCloak && h("p", {}, text("Frodo")),
  ])

Parameters

tag

Name of the node. For example, div, h1, button, etc. Essentially any HTML element or SVG element or custom element.

props

HTML or SVG properties ("props") for the DOM element are defined using an object where the keys are the property names and the values are the corresponding property values.

h("input", {
  type: "checkbox",
  id: "picard",
  checked: state.engaging,
})

Hyphenated props will need to be quoted in order to use them. The quotes are necessary to abide by JavaScript syntax restrictions.

h("q", { "data-zoq-fot-pik": "Frungy" }, text("The Sport of Kings!"))

Certain properties are treated in a special way by Hyperapp.

class:

The classes to use with the VNode. The class prop can be given in various formats:

  • As a string representing a class name. Because of the way Hyperapp internally processes class strings they're allowed to have a space-separated list of different class names.

    h("div", { class: "muggle-studies" })
    
  • As an object where the keys are the names of the classes while the values are booleans for toggling the classes.

    h("div", { class: { arithmancy: true, "study-of-ancient-runes": true } })
    
  • As an array that contains any combination of the various formats including this one.

    h("div", { class: ["magical theory", "xylomancy"] })
    

    This means the array format is recursive.

    h("input", {
      type: "range",
      class: [
        { dragonzord: state.green && !state.white },
        "mastodon",
        state.pink && "pterodactyl",
        [
          { triceratops: state.blue },
          "sabretooth-tiger",
          state.red && "tyrannosaurus",
        ],
      ],
    })
    

style:

The inline CSS styles to use with the VNode. The style prop can be an object of CSS properties where the keys are the CSS property names and the values are the corresponding CSS property values. Hyphenated CSS property names can either be in camelCase or quoted to abide by JavaScript syntax restrictions.

h(
  "span",
  {
    style: {
      backgroundColor: "white",
      color: "blue",
      display: "inline-block",
      "font-weight": "bold",
    },
  },
  text("+\\")
)

key:

A unique string per VNode that helps Hyperapp track if VNodes are changed, added, or removed in situations where it's unable to do so, such as in arrays.

const pokedex = (pokemon) =>
  h(
    "ul",
    {},
    pokemon.map((p) => h("li", { key: p.id }, text(p.name)))
  )

Event Listeners

Props that represent event listeners, such as onclick, onchange, oninput, etc. are where you would assign actions to VNodes.

Synthetic events can be added in the same way as long as their name starts with "on", so an event created with

const buildEvent = new Event("build")

can be used like this:

h("button", { onbuild: BuildAction }, text("Click Me"))

children

The children of the VNode are other VNodes which are directly nested within it.

children can either be given as a single child VNode:

h("q", {}, text("There is no spoon."))

or as an array of child VNodes:

h("q", {}, [
  text("I know Kung Fu."),
  h("em", {}, text("Show me.")),
])

Other Considerations

JSX Support

Hyperapp doesn't support JSX out-of-the-box. That said you can use this custom JSX function to be able to use it.

import { h, text } from "hyperapp"

const jsxify = (h) => (type, props, ...children) =>
  typeof type === "function"
    ? type(props, children)
    : h(
        type,
        props || {},
        [].concat(...children).map((x) =>
          typeof x === "string" || typeof x === "number" ? text(x) : x
        )
      )

const jsx = jsxify(h) /** @jsx jsx */