react

"mulling over state management stuff"
raspasov 2021-04-11T09:13:14.088600Z

@lilactown This was a nice overview of how things work in different CLJS React wrappers. One extra trick I’ve used when using the #js {:cljs-props …} passed to my own components is to memoize that JS object; that way the objects are (identical? o1 o2) => true between renders (unless the :cljs-props data changes) which prevents extra re-rendering

lilactown 2021-04-11T14:26:45.089Z

are you doing that using React.memo , or some other way?

raspasov 2021-04-11T21:22:30.090500Z

Like that, just via CLJS memoize https://github.com/raspasov/alexandria-clj/blob/main/src/ax/react/core.cljs#L65 Additionally, I do use React.memo on all components, since I try to render only via props in most cases; Technically, using (memoize …) naively is a memory leak but it hasn’t caused problems for me for a very long time; Ideally, some sort of a caching elimination strategy can be used.

raspasov 2021-04-11T21:26:06.091100Z

Using React.memo here https://github.com/raspasov/alexandria-clj/blob/main/src/ax/react/core.cljc#L4

raspasov 2021-04-11T21:28:09.092Z

I am not sure if I can achieve the same effect of avoiding re-renders on the same props data just via React.memo… I haven’t tried.

raspasov 2021-04-11T21:31:34.093800Z

I believe React.memo checks for the JS equivalent of (identical? …) objects, if I remember correct; I can perhaps supply a custom comparison function via CLJS (= …) to React.memo and avoid (memoize …) https://reactjs.org/docs/react-api.html#reactmemo

lilactown 2021-04-11T23:06:45.094200Z

that's right

lilactown 2021-04-11T23:07:54.095400Z

IME over-memoizing can be a problem. A lot of React components construct data during render that gets passed in as props to other components; doing a deep equality check on this data every render can have non-negligible performance penalties

lilactown 2021-04-11T23:08:45.096200Z

especially if the data is similar shape and changes most of the time, it's the worst of all worlds: you do the deep equality check for comparison and then re-render anyway!

lilactown 2021-04-11T23:09:41.097400Z

that's the rationale behind helix following what React does: no memoizing by default, then you can easily opt in to doing identical?, and if needed you can opt in further to other equality checks e.g. using =

raspasov 2021-04-11T23:41:13.098900Z

If a data changes really often (like multiple times per second), I actually opt for using local state/hooks so I can isolate the re-render only to one specific component rather than rendering from the root… It does make a difference in performance for the better.

raspasov 2021-04-11T23:44:10.100600Z

But I do that very sparingly, only for performance reasons; that way most of the application stays “pure” and renders via props (easy to reason about) and only a few most perf. critical components that get updated very often get to re-render via local state/hooks.