Reputation: 1244
From the Reagent introduction, a simple timer component:
(defn timer-component []
(let [seconds-elapsed (r/atom 0)]
(fn []
(js/setTimeout #(swap! seconds-elapsed inc) 1000)
[:div
"Seconds Elapsed: " @seconds-elapsed])))
and below it reads
The previous example also uses another feature of Reagent: a component function can return another function, that is used to do the actual rendering. This function is called with the same arguments as the first one.
This allows you to perform some setup of newly created components without resorting to React’s lifecycle events.
Can someone remind me of the underlying principle here? Why do we need this anonymous function? Why not just
(defn timer-component []
(let [seconds-elapsed (r/atom 0)]
(js/setTimeout #(swap! seconds-elapsed inc) 1000)
[:div
"Seconds Elapsed: " @seconds-elapsed])))
Upvotes: 1
Views: 654
Reputation: 1244
Tl;dr: The anonymous function that is returned is the render
method, which every component must have. You can elide the anonymous function if you use the with-let
macro in Reagent.
The indispensable part of a React component is a render
function, which takes a single object argument and returns a React element. The difference between render
and the component constructor is that, while both methods are called upon construction, render
is called on each update. (For instance, if someone calls the setState
method of the component).
In the above example, the difference between the inner, anonymous function and the outer timer-component
function is the same as between render
and the constructor. Notice that the anonymous function closes over the variables bound in the let
clause, which allows it to be stateful. If timer-component
itself were the render
function, then it would be called on every update, and seconds-elapsed
would be endlessly reset to zero.
See the doc on the Reagent repo called "Creating Reagent Components".
Upvotes: 0
Reputation: 541
From what I remember, Reagent calls timer-component
every time it wants to render - potentially setting up the same piece of state (seconds-elapsed
) over and over again.
By returning that anonymous function instead, it tells Reagent "use this to render timer-component
". This way your state setup is separated from rendering, and like your doco quote says, its a way to perform state setup without using Reacts lifecycle events.
Hope that makes sense
Upvotes: 4