(fn [] ;; the inner, render function, potentially called many times.
[:div "Hello" @name-ratom])))
```
First, note this is a [Form-2](https://github.com/Day8/re-frame/wiki/Creating-Reagent-Components#form-2--a-function-returning-a-function)
`component` ([there are 3 forms](https://github.com/Day8/re-frame/wiki/Creating-Reagent-Components)).
Previously in this document, we've used the simplest, `Form-1` components (no setup was required, just render).
With `Form-2` components, there's a function returning a function:
- the returned function is the render function. Behind the scenes, Reagent will wrap this render function
in a `reaction` to make it produce new Hiccup when its input Signals change. In our example above, that
means it will rerun every time `name-ratom` changes.
- the outer function is a setup function, called once for each instance of the component. Notice the use of
'subscribe' with the parameter `:name-query`. That creates a Signal through which new values are supplied
over time; each new value causing the returned function (the actual renderer) to be run.
>It is important to distinguish between a new instance of the component versus the same instance of a component reacting to a new value. Simplistically, a new component is returned for every unique value the setup function (i.e. the outer function) is called with. This allows subscriptions based on initialisation values to be created, for example:
``` Clojure
(defn my-cmp [row-id]
(let [row-state (subscribe [row-id])]
(fn [row-id]
[:div (str "Row: " row-id " is " @row-state)])))
```
In this example, `[my-cmp 1][my-cmp 2]` will create two instances of `my-cmp`. Each instance will re-render when its internal `row-state` signal changes.
`subscribe` is always called like this:
```Clojure
(subscribe [query-id some optional query parameters])
```
There is only one (global) `subscribe` function and it takes one parameter, assumed to be a vector.
The first element in the vector (shown as `query-id` above) identifies/names the query and the other elements are optional
query parameters. With a traditional database a query might be:
```
select * from customers where name="blah"
```
In re-frame, that would be done as follows:
`(subscribe [:customer-query "blah"])`
which would return a `ratom` holding the customer state (a value which might change over time!).
So let's now look at how to write and register the subscription handler for `:customer-query`
```Clojure
(defn customer-query ;; a query over 'app-db' which returns a customer
[db, [sid cid]] ;; query fns are given 'app-db', plus vector given to subscribe
(assert (= sid :customer-query)) ;; subscription id was the first element in the vector
(reaction (get-in @db [:path :to :a :map cid]))) ;; re-runs each time db changes
;; register our query handler
(register-sub
:customer-query ;; the id (the name of the query)
customer-query) ;; the function which will perform the query
```
Notice how the handler is registered to handle `:customer-query` subscriptions.
**Rules and Notes**:
- you'll be writing one or more handlers, and you will need to register each one.
- handlers are functions which take two parameters: the db atom, and the vector given to subscribe.
-`components` tend to be organised into a hierarchy, often with data flowing from parent to child via
parameters. So not every component needs a subscription. Very often the values passed in from a parent component
are sufficient.
- subscriptions can only be used in `Form-2` components and the subscription must be in the outer setup
function and not in the inner render function. So the following is **wrong** (compare to the correct version above)
```Clojure
(defn greet ;; a Form-1 component - no inner render function
[]
(let [name-ratom (subscribe [:name-query])] ;; Eek! subscription in renderer
[:div "Hello" @name-ratom]))
```
Why is this wrong? Well, this component would be re-rendered every time `app-db` changed, even if the value
in `name-ratom` (the result of the query) stayed the same. If you were to use a `Form-2` component instead, and put the
subscription in the outer functions, then there'll be no re-render unless the value queried (i.e. `name-ratom`) changed.
### Just A Read-Only Cursor?
Subscriptions are different to read-only cursors.
Yes, `subscriptions` abstract away (hide) the data source, like a Cursor, but they also allow
for computation. To put that another way, they can create
derived data from `app-db` (a Materialised View of `app-db`).
Imagine that our `app-db` contained `:items` - a vector of maps. And imagine that we wanted to
display these items sorted by one of their attributes. And that we only want to display the top 20 items.
This is the sort of "derived data" which a subscription can deliver.
(And as we'll see, more efficiently than a Cursor).
## The Signal Graph
Let's sketch out the situation described above ...
`app-db` would be a bit like this (`items` is a vector of maps):
```Clojure
(def L [{:name "a" :val 23 :flag "y"}
{:name "b" :val 81 :flag "n"}
{:name "c" :val 23 :flag "y"}])
(def app-db (reagent/atom {:items L
:sort-by :name})) ;; sorted by the :name attribute
```
The subscription-handler might be written:
```Clojure
(register-sub
:sorted-items ;; the query id (the name of the query)
(fn [db [_]] ;; the handler for the subscription
(reaction
(let [items (get-in @db [:items]) ;; extract items from db
sort-attr (get-in @db [:sort-by])] ;; extract sort key from db
(sort-by sort-attr items))))) ;; return them sorted
```
Subscription handlers are given two parameters:
1.`app-db` - that's a reagent/atom which holds ALL the app's state. This is the "database"
on which we perform the "query".
2. the vector originally supplied to `subscribe`. In our case, we ignore it.
In the example above, notice that the `reaction` depends on the input Signal: `db`.
If `db` changes, the query is re-run.
In a component, we could use this query via `subscribe`:
```Clojure
(defn items-list ;; Form-2 component - outer, setup function, called once