What's the ideal way to invoke renders?
Consider a UI is derived entirely from a single state atom, where all updates go through the same codepath.
(def !state
(atom {}))
(rum/defc *app [app-state] ...)
(defn trigger!
[event]
;;update the application state
(swap! !state update-state-fn event)
;;re-render the application state
(.render js/ReactDOM
(*app trigger! @!state)
(.getElementById js/document "my-app")))
(trigger! :first-event-to-start-app)
One benefit of this rendering approach is that there is no distinction between the initial render and subsequent renders. No need to keep track of a React component, add watches to the state atom, or anything like that.
One downside is that if trigger! is called multiple times within a single frame, the React render function will run needlessly multiple times, when it really only needs to run once on the latest application state for a given frame.
Would it be better to do use requestAnimationFrame or mount the component once and then call rum/request-render?
What would that look like?
Does it make a difference if you know that the *app template will or will not execute within the 16ms frame limit?
Batching state updates via requestAnimationFrame is usually a way to go. I believe most React wrappers does so.
So basically it's better to control how you update state and let the library to handle an update on its own.