LiveComponent vs child LiveView

So I wanted to make sure to understand the different tradeoffs between LiveComponents and child LiveViews

If you have the need create a component that also needs state and handle events, you’ll need to reach for either a LiveComponent or a child LiveView.

The difference between them as far I as found out so far:

  • A LiveComponent runs in the parent LiveView process, whereas a child will run in it’s own process. This means that a crash in the LiveComponent crashes the parent. This is not the case for the child.
  • because a LiveComponent is not a process, it does not have handle_info. So if you need to interact with handle_info you’ll need to handle that in the parent.
  • A child LiveView can’t implement handle_params. I’m not sure how the lifecycle of a child LiveView works exactly.
  • You can’t pass assigns to a child LiveView easily. You can pass them via a session, or via sending messages I guess.
  • re-rendering of a child LiveView doesn’t happen automatically when the parent re-renders, even if the session data changes, no re-render is triggered.
  • When using a LiveComponent you’ll always need to pass phx-target to target the correct component. This means you might need to pass on the @myself to other components.

Can you fully encapsulate state/events in case you want to render it from multiple different parents?

I don’t think so, the parent always needs to know about handle_info in case of a LiveComponent.
And a child LiveView behaves completely differently regarding to passing assings and re-rendering.

Furthermore, when using LiveComponents you will need to pass on @myself down to all components that trigger any handle_event callbacks. Even if you nest your components only a little bit, this is a lot of passing this down.

When to choose a child LiveView over a LiveComponent?

I’m not sure I know good use cases.

Remarks?

Let me know where I’m wrong.

3 Likes

You can encapsulate the events by defining a function in the component’s module to attach the event handlers with attach_hook. That way you define it all once and just need to attach the hooks wherever the component is used.

def mount(...) do
  socket = 
    socket
    |> MyComponent.attach_hooks(...)

  {:ok, socket}
end

Never used a child liveview so nothing to add on that topic.

2 Likes

I’m enjoying your posts on this subject because I’ve started using child LiveViews and I’m running into the same types of issues.

I can think of two reasons to use a child LiveView over a Live Component:

  1. You absolutely cannot allow the child LiveView to crash the parent, so having it in its own process is valuable.
  2. You want the ease of being able to directly send a message to it. This second point isn’t very strong since you could just send the message to a Live Component’s parent and then let it re-render its child.

I came to the forum just now because I lost a bunch of time trying to get my child LiveView to re-render when I changed the params I’m passing it. Perplexity said it would work. :slight_smile:

3 Likes