Fork me on GitHub

is there a way to use componentDidCatch with Helix? (aka error boundaries:


there is, you can use defcomponent which defines a class component that you can implement componentDidCatch and other lifecycle methods


it's very under-documented tho


One of the only things I miss about reagent/re-frame when using helix is the ability to arbitrarily dispatch an event from the REPL? Has anyone solved this in a novel way? I feel like this is a limitation of React’s useContext mostly.


this is open and up to you to implement, there is the reducer hook, which takes a similar approach


The issue I was finding was that the hooks are only valid to call within a component


Whereas in re-frame, I can just (rf/dispatch … ) anywhere


you can pass something to your root component


here is an example of a mini-reframe in Helix:


(defonce dispatcher* (atom nil))
(defonce app-state* (atom {::counter 0}))

(defmulti dispatcher (fn [action data state] action))

(defmethod dispatcher ::count-up [_ data state]
  (update state ::counter #(inc (or % 0))))

(defn dispatch [state [action data :as foo]]
  (reset! app-state* (dispatcher action data state)))

(defn repl-dispatch [cmd]
  (@dispatcher* cmd))

(h/defnc MiniReframe []
  (let [[state dispatch] (hooks/use-reducer dispatch @app-state*)]
    (hooks/use-effect [dispatch] (reset! dispatcher* dispatch))
      (dom/button {:on-click #(dispatch [::count-up])} (::counter state)))))

  (repl-dispatch [::count-up]))


Very cool. Thanks!


one thing I've been doing some spending some hammock time on is a way to interact with React's low level stuff from a REPL

👍 6

today I had an idea for a new state management system, something to combine hooks convenience and Fulcro robustness, going to try a POC on it later, this could address some of the issue of REPL interaction too

👀 6

e.g. you can use the devtool hooks to get a reference to the currently rendered root fiber and traverse it to find components, inspect props and state, even get references to state setters & reducer dispatch fns which you can call to trigger renders

👀 3

> even get references to state setters & reducer dispatch fns which you can call to trigger renders Oh this could be a really cool way to interact with an app. I’ve been getting around this by doing something similar to what @U066U8JQJ shared above.


yeah the hooks are all there, the interface is what I'm still noodling on


sneak peak of my POC, showing a bit what user code may look like:

(h/defnc IKey [{:keys [attr]}]
  (let [state (use-root-state app [attr] {})]
    (dom/div "Render: " (pr-str (get state attr)))))

(h/defnc User [{:keys [user-id]}]
  (let [{:user/keys [id name] :as props}
        (use-entity-state app [:user/id user-id]
          [:user/id :user/name]
          {::load true})]
      (dom/button {:on-click #(update-state props (fn [x] (assoc x :user/id 1 :user/name "bla")))} "Set data")
      (dom/div "User")
      (dom/div "ID: " id)
      (dom/div "Name: " name))))

(h/defnc MyStateManager []
    (h/$ IKey {:attr :foo})
    (h/$ User {:user-id 123})
    (h/$ User {:user-id 123})
    (dom/button {:on-click #(update-state app (fn [x] (assoc x :foo "bar")))}
      "Change text")))


the idea is to use hooks to plug some components in a "application" managed upstream (currently passing by hand, but it can go in a context to avoid repetition and make a tree use the same consistent app)


then you can hook on some root part, or in some entity (kind like Fulcro does)


the hook includes a query, and notifications are saved to fire refresh on things on state updates


what I like about it is that is veery opt-in, you can add this just for the parts of application that you want shared data


and can freely combine with other sorts of local state, like the state hook


options like ::load true can make the component automatic trigger a remote load for that data, otherwise it just tries to denormalize it from the local db


I think there can be a lot of controls to decide how load should behave


looks really nice. this is the kind of use case that I built for


awesome, I’ll give that a try!