Search documentation of mob

# Mob.Event.Component behaviour (mob v0.6.18)

Copy Markdown View Source

Behaviour for stateful event-owning components.

See `guides/event_model.md` for the model. In short:

- Stateless components are plain functions: `(assigns) -> render_tree`. They have no event horizon — events fired inside their subtree resolve to the nearest stateful ancestor.
- Stateful components implement `Mob.Event.Component`. They own events fired in their subtree and may escalate semantic events to their parent.

This is the Mob equivalent of `Phoenix.LiveComponent`.

## Status

This is the interface declaration. The runtime that hosts these components — registering them in render trees, routing events to them, managing their lifecycle — is implemented incrementally:

1. Existing `Mob.Component` (a sibling concept for native_view widgets) remains the runtime for components that pair with custom native views.
2. `Mob.Event.Component` (this module) is the event-routing abstraction: a stateful owner of events for a subtree of standard widgets.
3. The two will likely merge once the new event model is plumbed end-to-end.

Until then, the Bridge module handles the legacy event shapes and the existing `Mob.Component` is the canonical stateful component.

## Callbacks

    defmodule MyApp.CheckoutForm do
      use Mob.Event.Component

      def mount(props, state), do: {:ok, Map.put(state, :email, "")}

      def render(state) do
        # return a render tree (uses Mob.UI helpers)
        %{type: :column, ...}
      end

      def handle_event(%Address{id: :email}, :change, value, state) do
        {:noreply, %{state | email: value}}
      end

      def handle_event(%Address{id: :submit}, :tap, _, state) do
        # Escalate to parent — this is the "semantic" event.
        send(state.parent_pid, {:form_submitted, state.email})
        {:noreply, state}
      end
    end

## Summary

### Callbacks

handle_event(addr, event, payload, state)
handle_info(message, state)
mount(props, state)
render(state)
terminate(reason, state)
update(props, state)

## Callbacks

# handle_event(addr, event, payload, state)

    @callback handle_event(
      addr :: Mob.Event.Address.t(),
      event :: atom(),
      payload :: term(),
      state :: map()
    ) :: {:noreply, map()}

# handle_info(message, state)

(optional)

    @callback handle_info(message :: term(), state :: map()) :: {:noreply, map()}

# mount(props, state)

    @callback mount(props :: map(), state :: map()) :: {:ok, map()} | {:error, term()}

# render(state)

    @callback render(state :: map()) :: map()

# terminate(reason, state)

(optional)

    @callback terminate(reason :: term(), state :: map()) :: term()

# update(props, state)

(optional)

    @callback update(props :: map(), state :: map()) :: {:ok, map()}