DEV Community

Cover image for Reagent 101 / why Form 2 components need to return a function
icncsx
icncsx

Posted on

Reagent 101 / why Form 2 components need to return a function

Let's take a look at a canonical example of a Form 2 component.

(defn app-view [] (let [counter (r/atom 0)] ;; setup (fn [] ;; render fn [:div [:p @counter] [:button {:on-click (fn [e] (swap! counter inc))} "Increment!"]]))) 
Enter fullscreen mode Exit fullscreen mode

We initialize some local state and return a function that returns some Hiccup. On click, we would see the correct behavior: the counter incrementing.

Imagine if we didn't return that inner function. What would happen?

(defn app-view [] ;; render fn (let [counter (r/atom 0)] ;; setup [:div [:p @counter] [:button {:on-click (fn [e] (swap! counter inc))} "Increment!"]])) 
Enter fullscreen mode Exit fullscreen mode

The counter feature would break. Remember: in a Form 2 component, we have an outer function that is run only once and an inner function that is run every time the component re-renders.

When we don't have an inner function, the outer function assumes the role of a render function.

In the example above, this means that app-view gets re-run every time the component renders. Do you understand the problem now? The component-state is getting re-created with every render. We get a new counter r/atom on each re-render.

If a component does not re-render, it may be because you're re-creating state on every re-render.

Warmly,
DH

Top comments (1)

Collapse
 
hayoung0lee profile image
Hayoung Lee(이하영)

Great article!