thomashoneyman / purescript-halogen-hooks

Reusable stateful logic in Halogen, inspired by React Hooks
https://thomashoneyman.com/articles/introducing-halogen-hooks
MIT License
114 stars 13 forks source link
halogen-hooks purescript purescript-halogen

Halogen Hooks

CI Latest release

Reusable stateful logic for Halogen, inspired by React Hooks.

Hooks offer a simpler mental model for writing stateful code in Halogen. They are a better alternative to higher-order and renderless components and offer a more convenient way to write most ordinary components. They can be incrementally adopted and require no changes to existing components in your application.

Note: Hooks can be used in production code today, but Hooks are not as performant as regular Halogen components. A Hooks-based component is typically 1.5x slower and uses 1.75x the memory of an equivalent Halogen component. In most use cases this performance difference is not noticeable, but keep this in mind if you are using Hooks in a large, performance-sensitive application. Please feel free to contribute performance improvements!

Learn more about Hooks:

  1. Read the blog post introducing Halogen Hooks
  2. Read the Halogen Hooks documentation
  3. View the component and custom hook examples
  4. View the Hooks recipes in the PureScript Cookbook

Installation

You can install Halogen Hooks with Spago:

spago install halogen-hooks

If Halogen Hooks is not available in your package set, add it to your project's packages.dhall file:

let additions =
  { halogen-hooks =
      { dependencies = [ "halogen" ]
      , repo = "https://github.com/thomashoneyman/purescript-halogen-hooks.git"
      , version = "main"
      }
  }

Quick start

All types and functions available in Hooks are exported from the Halogen.Hooks module, so you can access the entirety of Hooks with one import:

import Halogen.Hooks as Hooks

Halogen Hooks ensures Hooks are always evaluated in the same order. For that reason you should use do, bind, and pure as qualified imports from the Halogen.Hooks module. You will see compile-time errors if you forget!

This code replicates the Halogen basic button example which renders a count that is incremented on click:

myComponent = Hooks.component \_ input -> Hooks.do
  count /\ countId <- Hooks.useState 0

  Hooks.pure do
    HH.button
      [ HE.onClick \_ -> Hooks.modify_ countId (_ + 1) ]
      [ HH.text $ show count ]

Documentation

There are several resources to help you learn about Hooks:

Contributing

You can contribute to Halogen Hooks in many ways: