0

I'm evolving my way towards a suitable design for state with reagent given my project, and while still using distinct atoms (i'll probably switch to a single atom, but trying to explore the space of possibilities at present), I've tried to set up all state in the lexical context of the root component, as illustrated below. Idea is that this app-state is an ordinary clojure map where the value of each key is a reagent atom.

It receives an attrs map which is a prop (coming from data- attrs on the html element), and its job is to initialise an app-state map, which is not itself an r/atom, but contains r/atoms. The problem is, all of these r/atoms were defined with defonce when declared at the top of the file, which is what I've just switched from, and now the defonce semantics is lost & figwheel hot reloading is broken.

Is there a way to preserve reloadable code while setting up state in this style?

I cannot put a defonce inside a let, because subsequent times that is evaluated it will evaluate to nil.
Or is there some pattern I'm missing here.

(defn a-root-component [attrs]
  (let [app-state {:some-state (r/atom (:some-state attrs))}]
    (fn [attrs]
      [some-component app-state])))
mwal
  • 2,803
  • 26
  • 34
  • The way I got hot reloading back was to `defonce` all of the `r/atom`s at the top level of the `ns` individually, then *also* `defonce` `app-state`, an *ordinary map* which is fine being immutable: `(defonce app-state {:some-state some-ratom})`, because some-ratom is just the var which refers to the r/atom defined above. Then, in the form2 component's let, I `reset!` the individual r/atoms to their initial values from the prop, which "feeds through" directly into the "immutable" app-state map. It seems slightly repetitive, but this gives back figwheel hot reloading. – mwal Oct 15 '20 at 08:52

1 Answers1

1

Technically you could use memoize, but I wouldn't. By using memoize your introducing hidden global state, cleverly hidden where no one will think to look for it. Better to defonce your state outside your main component and be explicit about it.

Given the direction your moving I'd look carefully at things like re-frame and Keemcha which provide established patterns and tooling for working with centralized state in a sane way.

Walton Hoops
  • 864
  • 4
  • 14