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).
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)