anagrius

anagrius

Reassigning assigns in render

Hey,

I try to keep my application state free of derived state. So I don’t for instance have:

{a: 1, b: 2, sum: 3}

But rather compute the derived state when I need it.
In liveview applications you often need derived state while rendering HTML, and it natural to do the calculation once and store the derived state in assigns so it can be used with the @-notation:

<div><%= @sum %></div>

The alternative is of course:

<div><%= @a + @b %></div>

in this trivial example, but often it is much more complex calculations involving many inputs, and these have to be passed to the calculation function:

<div><%= calculate_derived_state(@a, @b, @settings.displayFormat, @x, @y, @z) %></div>

Again fine if it is used once or twice.

Reassigning assigns in function components is allowed which means I can do:

def some_component(assigns) do
    assigns = assign(assigns, :sum, assigns.a + assigns.b)
    ~H"""
    <div><%= @sum %>
    """
end

But this is not allowed in the top-level render function of a liveview or live-component.

So, my question: Why would I not just do:

def render(assigns) do
    ~H"""
    <.render_inner {assigns} />
    """
end

def render_inner(assigns) do
      assigns = assign(assigns, :sum, assigns.a + assigns.b)
     ~H"""
      <div><%= @sum %></div>
     """
end

I understand that sum is calculated each render, but that is a small cost to avoid managing stale derived state.

Is there some hidden cost I don’t see? Doe passing {assigns} to render_inner for instance for the rendering of the entire view-tree or something.
I understand that render_inner must be recalculated on each render - but that should be equivalent to what render would do anyway.

Marked As Solved

sodapopcan

sodapopcan

Oh right you are. Should probably report that as it’s quite confusing, especially when it does indeed say “can’t” when you clearly can. I’ve been doing this for years at this point, though, lol. Only once in a while, but never thought too much about it.

Where Next?

Popular in Questions Top

lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New

Other popular topics Top

KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36820 110
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New

We're in Beta

About us Mission Statement