Module

Halogen.Hooks.Component

#component

component :: forall hooks q i s o m. (ComponentTokens q s o -> i -> Hook m hooks (ComponentHTML (HookM m Unit) s m)) -> Component q i o m

Produces a Halogen component from a Hook which returns ComponentHTML. If you need to control whether Hooks evaluate when new input is received, see memoComponent.

Tokens are provided which enable access to component-only features like queries, output messages, and child slots, which don't make sense in a pure Hook context.

myComponent :: forall q i o m. H.Component q i o m
myComponent = Hooks.component \tokens input -> Hooks.do
  ... hook implementation

If you don't need to use tokens or input, you can use underscores to throw away those arguments.

myComponent :: forall q i o m. H.Component q i o m
myComponent = Hooks.component \_ _ -> Hooks.do
  ... hook implementation

If you are using tokens provided by the component function, you will have better type inference if you annotate the token type:

type Tokens = Hooks.ComponentTokens MyQuery MySlots MyOutput

myComponent :: forall i m. H.Component MyQuery i MyOutput m
myComponent = Hooks.component \(tokens :: Tokens) _ -> Hooks.do
  ... hook implementation

Use type variables to substitue unused token types:

type Tokens s o = Hooks.ComponentTokens MyQuery s o

myComponent :: forall i o m. H.Component MyQuery i o m myComponent = Hooks.component (tokens :: Tokens _ o) _ -> Hooks.do ... hook implementation


#memoComponent

memoComponent :: forall hooks q i s o m. (i -> i -> Boolean) -> (ComponentTokens q s o -> i -> Hook m hooks (ComponentHTML (HookM m Unit) s m)) -> Component q i o m

A version of component which allows you to decide whether or not to send new input to the hook function based on an equality predicate. Halogen components send input to children on each render, which can cause a performance issue in some cases.

myComponent :: forall q o m. H.Component q Int o m
myComponent = Hooks.memoComponent eq \tokens input -> Hooks.do
  -- This hook implementation will not run when it receives new input
  -- unless the `Int` has changed.

Some input data may be more expensive to compute equality for than to simply send input again. In these cases you may want to write a more sophisticated equality function -- for example, only checking by a unique ID.

type User = { uuid :: Int, info :: HugeObject }

eqUser :: User -> User -> Boolean
eqUser userA userB = userA.uuid == userB.uuid

myComponent :: forall q o m. H.Component q User o m
myComponent = Hooks.memoComponent eqUser \_ input -> Hooks.do
  -- This hook implementation will not run when it receives new input
  -- unless the `User`'s id has changed.

Modules