Why does updating my nested Reagent component not update it?

94 views Asked by At

I have a triply nested component (in different files) in Reagent + ShadowCLJS. When editing and saving this file, the changes don't show immediately until editing and saving the parent component.

For example, NAV is nested in DASHBOARD which itself is nested in APP. Editing and saving DASHBOARD result in changes also in the browser, but editing and saving NAV does not, until DASHBOARD itself is modified, then NAV will show changes in the browser.

Example code:

(ns app.core
  (:require [app.views.dashboard :as dash]))
(defn app[]
  [dashboard])
(ns app.views.dashboard
  (:require [app.components.nav :as nav]))
(defn dashboard[]
  [:div 
    [:div "Dashboard"]
    [nav/nav]])
(ns app.components.nav)
(defn nav[]
  [:div "Navigation"])

Build configuration:

;;shadow-cljs.edn
...
{:app {:target :browser
       :modules {:main {:entries [app.core]}}}
...

I tried un-nesting the namespaces so that the components live next to each other in the directory, but still triply nested. This also does not work.

2

There are 2 answers

1
Thomas Heller On BEST ANSWER

I wrote about hot-reload in CLJS, maybe you can find an answer there.

Normally I'd expect your setup to just work, but I suspect that reagent/react decides to skip rendering at some point. They memoize some components and since CORE doesn't change, when touching NAV it may decide that nothing needs to be done.

You can force a full reload by setting :devtool {:reload-strategy :full} in your build config, which should address this problem. It may however become somewhat slow in larger builds.

0
Somé On

After 5 hours of meddling around, it turns out if C is nested in B which is nested in A (A (B (C))), not only do you have to import C inside B, but you also have to import it inside A. So my solution was to also :require app.components.nav inside app.core.

I'm not very sure why this behaves like this, so if anyone else would like to respond with an explanation, that would be welcome!