Skip to content

Commit

Permalink
Improve assigns-eex.md
Browse files Browse the repository at this point in the history
  • Loading branch information
josevalim authored Jun 9, 2024
1 parent adacdfd commit cea2ab2
Showing 1 changed file with 18 additions and 11 deletions.
29 changes: 18 additions & 11 deletions guides/server/assigns-eex.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ enforces this best practice.
There are some common pitfalls to keep in mind when using the `~H` sigil
or `.heex` templates inside LiveViews.

### Variables

Due to the scope of variables, LiveView has to disable change tracking
whenever variables are used in the template, with the exception of
variables introduced by Elixir block constructs such as `case`,
Expand Down Expand Up @@ -119,14 +121,12 @@ for LiveViews or LiveComponents:
"""
end

Instead explicitly precompute the assign outside of render:
Instead use the `assign/2`, `assign/3`, `assign_new/3`, and `update/3`
functions to compute it:

assign(socket, sum: socket.assigns.x + socket.assigns.y)
assign(assigns, sum: assigns.x + assigns.y)

Unlike LiveView's `render/1` callback, a function component can
modify the assigns it receives via the `assign/2`, `assign/3`,
`assign_new/3`, and `update/3` functions. Therefore, you can assign
the computed values before declaring your template:
The same functions can be used inside function components too:

attr :x, :integer, required: true
attr :y, :integer, required: true
Expand All @@ -139,20 +139,24 @@ the computed values before declaring your template:
end

Generally speaking, avoid accessing variables inside `HEEx` templates, as code that
access variables is always executed on every render. This also applies to the
`assigns` variable. The exception are variables introduced by Elixir's block
constructs. For example, accessing the `post` variable defined by the comprehension
below works as expected:
access variables is always executed on every render. The exception are variables
introduced by Elixir's block constructs. For example, accessing the `post` variable
defined by the comprehension below works as expected:

```heex
<%= for post <- @posts do %>
...
<% end %>
```

### The `assigns` variable

When talking about variables, it is also worth discussing the `assigns`
special variable. Every time you use the `~H` sigil, you must define an
`assigns` variable, which is also available on every `.heex` template.
However, we must avoid accessing this variable directly inside templates
and instead use `@` for accessing specific keys. This also applies to
function components. Let's see some examples.

Sometimes you might want to pass all assigns from one function component to
another. For example, imagine you have a complex `card` component with
Expand Down Expand Up @@ -205,7 +209,8 @@ end
```

If you really need to pass all assigns you should instead use the regular
function call syntax:
function call syntax. This is the only case where accessing `assigns` inside
templates is acceptable:

```elixir
def card(assigns) do
Expand All @@ -224,6 +229,8 @@ is passed to each child component, only re-rendering what is necessary.
However, generally speaking, it is best to avoid passing `assigns` altogether
and instead let LiveView figure out the best way to track changes.

### Summary

To sum up:

1. Avoid defining local variables inside HEEx templates, except within Elixir's constructs
Expand Down

0 comments on commit cea2ab2

Please sign in to comment.