OM Components vs plain functions
Asked Answered
E

2

8

I am going through this OM tutorial but it's not clear to me when to use OM components vs plain functions (in particular the om/component macro).

The tutorial writes:

The first argument is a function that takes the application state data and the backing React component, here called owner. This function must return an Om component - i.e. a model of the om/IRender interface, like om.core/component macro generates

; here the function (fn [app owner]) indeed returns an OM component
(om/root
  (fn [app owner]
    (om/component (dom/h2 nil (:text app))))
  app-state
  {:target (. js/document (getElementById "app"))})

In the next section we find the following example of a rendering loop for a list:

 ; this one does not return an om component (or does it?). it returns a virtual dom
(om/root
  (fn [app owner]
    (apply dom/ul nil
      (map (fn [text] (dom/li nil text)) (:list app))))
  app-state
  {:target (. js/document (getElementById "app0"))})

Here, we're basically just returning a (virtual) dom directly, not wrapped in an OM component, so the question would be: Why does the om/component macro exist? The macro simply helps us to reify the IRender function, but it appears that we can also just use plain functions for that. I would reify OM components that have lifecycle state (or need the owner to call get-props) but for components that just need to create virtual dom I'd rather go for simple functions (so I don't need the build/build-all functions to create my virtual dom). What am I missing here? Why is the macro still useful (and I don't see it).

Equivocation answered 28/6, 2014 at 11:39 Comment(0)
S
9

I had this same question last week, and I dug through the Om source code to find out.

I couldn't find any functional difference between using the om/component macro and not. But maybe this info can shed some light on someone who knows more about React.

Any function f passed to om/root (and subsequently om/build) is placed inside of a container Om component. This Om component is just a dummy React component that forwards all life-cycle events to the result of f if it implements Om's lifecycle protocols (i.e. when it is a reify object).

If the result of f is not a reify object that implements those protocols, it is assumed to be a React component, and it is used as the value returned by the render lifecycle function.

(relevant: Om's render function here)

Slap answered 3/7, 2014 at 0:10 Comment(1)
Okay, then I get it. So the macro might be there when you want to wrap a plain react component into an OM component. Maybe future versions of OM will have slighly different semantics in the om/component macro, so you better use the macro even all you have to do is to return a react component.Equivocation
T
3

The om/component macro is just a shorthand for the defn and reify combination when you do not need to pass in state

Tenure answered 1/7, 2014 at 7:2 Comment(1)
That's part of the story. From the docs, "Sugar over reify for quickly putting together components that only need to implement om.core/IRender and don't need access to the owner argument."Aeolotropic

© 2022 - 2024 — McMap. All rights reserved.