How does `update/2` only receive "new" assigns in a LiveComponent?

Can someone clarify what this sentence means in the docs for LiveComponent?

The assigns received as the first argument of the update/2 callback will only include the new assigns passed from this function. Pre-existing assigns may be found in socket.assigns.

I don’t get it - under what circumstances is an assign considered “new”? Afaict all assigns always get passed, even the ‘old’ ones.

E.g. say that @bar = 1 in my parent LV, then I have:

<.live_component component={Something} id="id" foo="foo" bar={@bar} />

Then if I stick an IO.inspect in Something.update/2 I see that assigns is %{id: "id", foo: "foo", bar: 1}.

Then say I update the value of @bar to 2, which triggers another update. If I’m reading the docs correctly then only the bar assign should be passed to update/2 this time, but from IO.inspect I can see that the assigns passed to update/2 is now %{id: "id", foo: "foo", bar: 2} - all the keys are included, not just the “new” one.

This is still the case if I engineer some contrived situation where live_component/1 doesn’t receive the key at all on the first update but receives it on later updates… all of the original keys are still included on every update.

The docs imply that an attribute/value pair passed to live_component/1 might not always be passed to update/1, but I can’t see how this is ever actually the case. What am I not understanding?

That is a confusing sentence. What function is it referring to as “this function”?

I would expect only new assigns are passed to update when the Live component is updated via send_update.

1 Like