Halogen when to spilt components (and drag and drop)

At the moment i have just a static html halogen component. How do i know when to create sub-components?

Also i like to drag and drop with these events https://pursuit.purescript.org/packages/purescript-halogen/4.0.0/docs/Halogen.HTML.Events#v:onDrag (halogen 5 version if available).

Is it useful to keep drag and drop within the same component ? Or better split draggable from droparea in separate components? (two lists both have draggable items and are droppable)

I believe the guideline is to try to minimize the number of components.

Here are two discussions I found on the subject:

So you’ll likely have the easiest time by starting with your two lists in the same component.

1 Like

In general my approach is:

  1. Start with a function which produces plain HTML (often literally the PlainHTML type)
  2. If it needs state, pass that state as an input to the function but store & manage that state in a parent component
  3. If it needs a behavior, pass the relevant action as an input to the function and use it as an event handler but handle the action in a parent component
  4. If you want to reuse this function with its state and actions with multiple parent components, then write a type synonym for its relevant state and a helper function to use for its actions in the parent handleAction

The previous steps are a spectrum: if at any point along the way from 1-4 you feel like this is just too much to be managing in a parent component, switch to encapsulating the state and behaviors in a child component instead.

So to answer your question I would try using one component and have drag and drop together, and if it starts to feel like too much then try splitting into sub components.

Usually I find that as soon as I switch from one component to multiple that it becomes obvious pretty quickly whether it was a good idea or not.

You may also be interested in this similar discussion on Real World Halogen with @cmdv:

3 Likes

Thanks for the answer guys, it’s already very helpful.

What if i want to swap out a part of the page with something else? Is that reason for a component? Or is there another way to do this.

I would again start with the plain HTML and use case or if or guard statements to conditionally render the right ones based on the state. And I’d move through the same progression above.

type State = { loggedIn :: Boolean }

pagePartA = HH.text "A"
pagePartB = HH.text "B"

component = H.mkComponent
  { initialState: \_ -> { loggedIn: false }
  , eval:  H.mkEval H.defaultEval
  , render: \{ loggedIn }. ->
      HH.div
         []
         [ if loggedIn then pagePartA else pagePartB ]
   }
1 Like