docs-actions.md
Actions in Hologram are client-side operations that allow you to:
They are typically executed in response to user interactions, enabling dynamic and interactive web applications.
Actions are defined as functions in your page or component modules using the following syntax:
def action(name, params, component) do
# Action logic here
end
For example:
def action(:update_count, params, component) do
put_state(component, :count, params.new_count)
end
Actions receive three arguments:
name - the atom representing the action name
params - a map containing:
Custom parameters that can come from:
put_action/3put_action/3Event data under the :event key (see Events for details about event data)
component - the current %Component{} struct
Actions must return a %Component{} struct. This struct not only reflects changes to the component's state but also includes instructions for what happens next through functions that can be called on it. These functions are pure - they don't cause any side effects and simply return a new modified %Component{} struct. Since these functions return the modified %Component{} struct, they can be chained together using the pipe operator |>, allowing for a clean and composable way to combine multiple state changes and behaviors.
Within an action, you can:
By setting the value for a single key:
put_state(component, :key, value)
With multiple key-value pairs using a keyword list:
put_state(component, key_1: value_1, key_2: value_2)
With multiple key-value pairs using a map:
put_state(component, %{key_1: value_1, key_2: value_2})
Update a nested value by specifying a path of keys:
put_state(component, [:path_key_1, :path_key_2], value)
Command with the specified name without any parameters:
put_command(component, :my_command)
Command with the specified name and additional parameters provided as a keyword list:
put_command(component, :my_command, param_1: value_1, param_2: value_2)
Command with a specified name, target, and parameters using a map for the parameters (in this longhand version, both params and target are optional):
put_command(component, name: :my_command, target: "other_component", params: %{key: value})
Command using a %Command{} struct:
put_command(component, %Command{name: :my_command})
See also: Commands.
Page without params:
put_page(component, ProductsPage)
Page with params:
put_page(component, ProductPage, product_id: 123)
By setting a value for a single key:
put_context(component, :key, value)
Using a tuple for namespacing, allowing different components to use the same key without conflict:
put_context(component, {MyModule, :key}, value)
See also: Context.
Action with the specified name without any additional parameters:
put_action(component, :my_action)
Action with the specified name and additional parameters provided as a keyword list:
put_action(component, :my_action, param_1: value_1, param_2: value_2)
Action using the longhand syntax (where params, target, and delay are optional):
put_action(component, name: :my_action, target: "other_component", params: %{key: value})
Using an %Action{} struct:
put_action(component, %Action{name: :my_action})
Actions can be triggered using event attributes in templates. For detailed information about event binding syntax and available event types, see the Events documentation.
By default, actions are executed on the component that contains them. If the component is stateless (doesn't have a CID specified), the closest stateful component higher in the hierarchy is used. You can specify a different component for execution using the target parameter. For more information about event targets, see the Events documentation.
Actions can be scheduled to execute after a specified delay using the delay parameter, which accepts a value in milliseconds.
The delay can be specified in several ways:
$click={action: :my_action, delay: 750}put_action/2: put_action(component, name: :my_action, delay: 750)Common use cases include:
Note: The delay parameter is only available for actions, not commands.
Here's a simple example that demonstrates how actions work in Hologram. The counter component shows:
%Component{} struct using the pipe operator:
put_state/3put_command/3defmodule MyApp.Components.Counter do
# ...
def template do
~HOLO"""
<div>
<p>Count: {@count}</p>
<button $click={:increment, step: 1}> +1 </button>
</div>
"""
end
def action(:increment, params, component) do
new_count = component.state.count + params.step
component
|> put_state(:count, new_count)
|> put_command(:save_count, new_count)
end
# ...
end
Sponsored by
Previous
Next