Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ratoms in children-as-function do not trigger re-renders #371

Open
lilactown opened this issue Apr 30, 2018 · 2 comments
Open

Ratoms in children-as-function do not trigger re-renders #371

lilactown opened this issue Apr 30, 2018 · 2 comments

Comments

@lilactown
Copy link

See my notes over on react-context. Basically:

(def state (r/atom "initial")

(defn component []
  [other-component
    (fn [value]
        [:div @state])])

If state changes (via e.g. swap! or reset!), the component inside of the function passed into other-component will not re-render reactively.

@Deraen
Copy link
Member

Deraen commented May 4, 2018

The problem here (as far as I understand and can describe) is that the function doesn't have Reactive context. There are several workarounds like:

  • Dereffing the value outside of the function
  • Adding another component which does the deref

Second one works because as-element creates another component which has proper context.

I think the fix for this would be to ensure the function uses the context of the main component.

(defonce my-context (react/createContext "default"))

(def Provider (.-Provider my-context))
(def Consumer (.-Consumer my-context))

(def consumer (r/adapt-react-class Consumer))

(def state (r/atom "initial"))

(defn inner []
  (js/console.log "reactive?" (ratom/reactive?))
  [:div @state])

;; this one works
(defn component []
  [consumer {}
   (fn [value]
     (r/as-element [inner]))])

;; doesn't work
(defn component []
  [consumer {}
   (fn [value]
     (js/console.log "reactive?" (ratom/reactive?))
     (r/as-element [:div @state]))])

;; Use
(r/render
  [:div
   [component]
   [:button
    {:on-click #(reset! state "foo")}
    "x"]])

@Deraen Deraen added the bug label May 4, 2018
@Deraen
Copy link
Member

Deraen commented May 4, 2018

Reagent components are rendered using run-in-reaction:
https://github.com/reagent-project/reagent/blob/master/src/reagent/ratom.cljs#L502-L511

That will call the render fn in deref-capture:
https://github.com/reagent-project/reagent/blob/master/src/reagent/ratom.cljs#L39-L49

*ratom-context* alone is not enough to get derefs registered, the function body also has to be evaluated during deref-capture of main component. I'm not sure if this is possible.

One solution could be to provide some utilities (and documentation) to guide users to use e.g. second workaround.

@Deraen Deraen removed the bug label Jan 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants