Giter Club home page Giter Club logo

Comments (4)

tonsky avatar tonsky commented on July 19, 2024

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.

lynaghk avatar lynaghk commented on July 19, 2024

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.

lynaghk avatar lynaghk commented on July 19, 2024

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.

roman01la avatar roman01la commented on July 19, 2024

@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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.