Om components

We will keep our components in the ui.cljs file:

(ns contacts.ui
(:require [om.next :as om :refer-macros [defui]]
[om.dom :as dom]))

(defui RootView
static om/IQuery
(query [this]
(let [subquery (om/get-query Contact)]
`[{:list/contacts ~subquery}]))
Object
(render [this]
(let [{:keys [list/contacts]} (om/props this)]
(dom/div nil
(apply dom/div nil
[(dom/h2 nil "Contacts")
(list-view contacts)])))))

This snippet introduces a number of new features and terminology, so it deserves a few paragraphs.

When describing om/add-root!, we saw that its second argument must be an Om component. The defui macro creates one. The Om component uses a single function, renderwhich gets called when the application state changes and components need to be displayed. The render function must return an Om/React component or something React knows how to render, such as a DOM representation of the component. Om components are pure JavaScript objects.

The dom namespace contains thin wrappers around React's DOM classes. It's essentially the data structure representing what the application will look like. Its first argument is a hash map representing HTML attributes. Components in the RootView component do not need any attributes, so we pass nil to them. We will see examples of passing hash maps into the Contact component in the following subsections.

This time, we give, as the second argument to dom/div, a hash map representing HTML attributes. Next, we will look at two examples of how we can create Om components inside another Om component. We simply pass them as the second argument to dom/div.