diff --git a/guides/server/assigns-eex.md b/guides/server/assigns-eex.md index c086caa9d3..670a75a9bb 100644 --- a/guides/server/assigns-eex.md +++ b/guides/server/assigns-eex.md @@ -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`, @@ -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 @@ -139,10 +139,9 @@ 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 %> @@ -150,9 +149,14 @@ below works as expected: <% 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 @@ -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 @@ -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