sending updates or messages to live_components without having all assigns necessarily

Hi !
I have a question about the usual way to send a message to a component without using send_update/2. In fact, I work on a project with many components and it’s important to limit renderings that could make the app slower. The main LiveView is DashboardLive, on the dashboard_live.html.leex a component named LiveComponent.Tree is called for every @first_pages :

<section id="pages" phx-update="append">
            <%= if @pages != [] do %>
                <%= for page <- @first_pages do %>
                    <%= live_component MyApp.LiveComponent.Tree,
                    id: "tree-#{page.id}-child",
                    page: page,
                    pages: get_children(page.id),
                    ancestors: [],
                    available_purposes: [],
                    translate: @translate,
                    language: @service.language,
                    clear: false,
                    parent_id: "none",
                    display_children: true,
                    current_page: @page %>
                <%end%>
            <%end%>
        </section>

That component is recursive and calls itself in its render to display all pages :

def render(assigns) do
    ~L"""
      <div id=<%= @id <> "-tree" %> class="branch pos-relative grid auto-flow column mc">
        <%= if @page != nil do %>
          <%= live_component MyApp.LiveComponent.Page,
              id: @id <> "-page",
              page: @page,
              parent_id: @parent_id,
              translate: @translate,
              language: @language,
              available_purposes: @available_purposes,
              clear: @clear,
              current_page: @current_page %>
        <% end %>
        <%= if @clear do %>
          <div id=<%= @id <> "-hline" %> class="horizontal-line pos-absolute"></div>
        <% end %>
        <%= if @pages != [] do %>
          <div  id=<%= @id <> "-rline" %> class="right-line pos-absolute"></div>
          <%= if @display_children do %>
            <button id=<%= @id <> "-less" %> class="reduce-button" phx-target="<%= @myself %>" phx-click="toggle-display-children" >
              <img id=<%= @id <> "-img-less" %> src="<%= Routes.static_path(@socket, "/images/remove-white-18dp.svg") %>" width="18px" height="18px"/>
            </button>
            <div id=<%= @id %> class="children">
              <%= for page <- @pages do %>
                <%= live_component MyApp.LiveComponent.Tree,
                id: @id <> "-#{page.id}",
                page: page,
                parent_id: @page.id,
                pages: get_children(page.id, @ancestors),
                ancestors: [@page.id | @ancestors],
                available_purposes: @available_purposes,
                translate: @translate,
                language: @language,
                clear: true,
                display_children: true,
                current_page: @current_page %>
              <% end %>
            </div>
          <% else %>
            <button id=<%= @id <> "-more" %> class="expand-button" phx-target="<%= @myself %>" phx-click="toggle-display-children" >
              <img id=<%= @id <> "-img-more" %> src="<%= Routes.static_path(@socket, "/images/add-white-18dp.svg") %>" width="18px" height="18px"/>
            </button>
          <% end %>
        <% end %>
      </div>
     """
  end

So, as you can see, LiveComponent.Page is the component that will display each pages. The same page can be present at several places in the tree, and when a LiveComponent.Page has the same id as @current_page, it need to change class to “current”.

defp article_classes(_, nil), do: "thumbnail"
defp article_classes(page, current_page) do
  if page.id == current_page.id do
    "thumbnail current"
  else
    "thumbnail"
  end
end

To limit renderings, I thought it could be great if I could trigger only components that needs to be updated, for example changing @current_page assign only when it’s necessary (for previous components that have the same id as @current_page to remove the “current” class and vice-versa). Some assigns like @ancestors depends on the place of the component on the tree, so we can’t have access to them in the main LiveView to make a send_update/2.

Any help could be precious :slight_smile:

Some assigns like @ancestors depends on the place of the component on the tree, so we can’t have access to them in the main LiveView to make a send_update/2 .

You can always use send(self(), {:any, foo, bar, etc}) from the component to send whatever data is missing from the main LiveView.