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!"]])))
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!"]]))
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)
Great article!