Comments (4)
a custom mixin maybe? The one that will only compare arguments you need?
Take a look at rum/static, itβs code is trivial
On Mon, Jul 13, 2015 at 2:32 AM Kevin Lynagh [email protected]
wrote:
I'm using Rum to build reusable components.
These components typically don't have local state --- they're "controlled
components" that take a value and on-change callback as arguments:(rum/defc *color-picker < rum/static
[color on-change]
[:input {:type "color" :value color :on-change #(on-change (.-value (.-target %)))}])Their parents use this callback to propagate new values across the app:
(rum/defc _parent < rum/static
[parent-id color]
[:div
[:h1 {:style {:background-color color}} parent-id]
(_color-picker color #(update-color-elsewhere-in-app! parent-id %))])Semantically everything works great, but I'm having trouble with
performance.
Using rum/static doesn't help because the on-change callbacks are
anonymous functions --- on each render of the parent's body, a new
on-change is created that is not equal to the previous on-change callback.Are there any recommended patterns for handling this situation?
The only solution I can think of is to pass the functions in as vars
rather than closures.
E.g., the above example would become:(rum/defc *color-picker < rum/static
[color on-change-args]
[:input {:type "color" :value color :on-change #(apply (first on-change-args) (rest on-change-args) (.-value (.-target %))}])(rum/defc _parent < rum/static
[parent-id color]
[:div
[:h1 {:style {:background-color color}} parent-id]
(_color-picker color [update-color-elsewhere-in-app! parent-id]))])but this doesn't strike me as a great solution.
β
Reply to this email directly or view it on GitHub
#34.
from rum.
I'm hoping to come up with a general solution for the problem of callbacks --- ignoring them won't always yield correct behavior.
E.g., if the color-picker is part of a "background color for selected object" palette that is always mounted and the on-change
callback passed to it varies depending on the currently selected object, than we do want to re-render the picker when a new object is selected and a new on-change
callback is given to the color picker.
Another way of framing the problem is thinking about partial application --- I want:
(= (partial f 1 2 3)
(partial f 1 2 3))
(not= (partial f 1 2 3)
(partial f 2 3 4))
from rum.
The best I've been able to do is implement the closure manually using defrecord
.
In my application I pass DataScript transaction data to a global trigger!
function, so the callback record looks like:
(defrecord CallbackTxAdd
[trigger! id attr]
IFn
(-invoke [_ val]
(trigger! :transact {:tx-data [[:db/add id attr val]]})))
This record can be passed in like this:
(*color-picker color (CallbackTxAdd. trigger! parent-id :style/color))
and pure rendering works as I'd like, because of record equality:
(= (CallbackTxAdd. trigger! parent-id :style/color)
(CallbackTxAdd. trigger! parent-id :style/color))
;;=> true
Leaving this issue open in case anyone wants to propose alternatives.
(@tonsky feel free to close, of course, if you'd rather this sort of discussion happen outside of the issue tracker.)
from rum.
@lynaghk These days callback caching can be handled using React.useCallback
hook. The only thing missing is rum.core/static
for functional components, see #202
I'm gonna close this issue.
from rum.
Related Issues (20)
- rum/fragment with React components HOT 2
- optimizations :advanced (shadow-cljs) failing on simple :form :input
- defc error with shadow-cljs. Makes Rum unusable for me... :( HOT 22
- daiquiri: fragment? fails on vectors HOT 13
- Question about rendering performance when updating state asynchronously HOT 9
- should-update error
- Big performance regression between 0.11.5 and 0.12.3 HOT 9
- Server/client difference when rendering nil HOT 2
- require-lazy macro unnecessarily prescriptive about namespace/module structure HOT 1
- Error when use `rum/local` and `rum/use-callback` together HOT 2
- Hydration not fully compatible with React 18 HOT 4
- bind-context produces unfixable infer warnings HOT 3
- `with-key` and `with-ref` Removing children? HOT 2
- ClojureScript >=1.11.51 seems to break Rum HOT 4
- ClojureScript >=1.11.51 seems to break Rum HOT 3
- How to use daiquiri.core/html ? HOT 9
- How can I use npm based react library I rum ssr mode HOT 4
- Live Examples Missing HOT 1
- Hulunote(a tool for networked thought) use the rumπ
- Interpretation warnings print var symbol instead of the value
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rum.