helix

https://github.com/Lokeh/helix
Saikyun 2020-04-03T05:34:49.089600Z

hello, I'm a bit curious about helix and have read a bit on the github page. one thing I'm wondering is how one would handle "global" state. would I have to deal with js objects and send them as props, and then create new js-objects in order to trigger rerenders? or can I use a hash-map and send it as props? trying to wrap my head around it 🙂

Saikyun 2020-04-03T05:41:46.092400Z

to be a bit more concrete: • I make an edit-form • I have some "server side" rendered data, e.g. (def form-state {:name "Saikyun", :job "clojure-lover"}) • in reagent I would've made this into an r/atom, and in the form put things like: [:input {:value (:name @form-state)}]. but how would I do something similar in helix? 🙂

oconn 2020-04-03T13:17:02.095Z

https://reactjs.org/docs/hooks-reference.html#usecontext may be an option for handling global state https://reactjs.org/docs/hooks-state.html

oconn 2020-04-03T13:19:49.096700Z

If you are just concerned about the local state of the form you could probably use the use-effect and use-state hooks

lilactown 2020-04-03T14:56:27.097800Z

hey @saikyun! 🙂 no, helix handles creating any necessary JS objects, if your components are written with it.

lilactown 2020-04-03T15:01:49.102600Z

I’d have to understand a bit more what you’re trying to do. I’ll try and explain a couple different cases. first, if you just want to use the server rendered data as some default state inside a component:

(def default-form-state {:name "Saikyun", :job "clojure-lover"})

(defnc form
  []
  (let [[{:keys [name]} set-state] (hooks/use-state initial-form-state)]
    (d/input {:value name :on-change #(set-state assoc :name (.. % -target -value))})))
and this would initialize the local component state with default-form-state. Editing the name using the input will save those changes locally to the component. If you clear my-form and then render it again some time else, it will render with the default-form-state again.

lilactown 2020-04-03T15:07:45.107300Z

if you wanted to share this state between two components, then you could move the use-state call into a shared parent between the two components:

(defnc name-form
  [{:keys [name on-change]}]
  (d/input {:value name :on-change #(on-change (.. % -target -value))}))

(defnc job-form
  [{:keys [job on-change]}]
  (d/input {:value job :on-change #(on-change (.. % -target -value))}))

(defnc form
  []
  (let [[form-state set-form] (hooks/use-state default-form-state)]
    ($ name-form 
       {:name (:name form-state)
        :on-change #(set-form assoc :name %)})
    ($ job-form
       {:job (:job form-state)
        :on-change #(set-form assoc :job %)})))

lilactown 2020-04-03T15:09:57.108800Z

finally, let’s say you have 19 deeply nested components all over the place that all need this form state. first of all, I’m sorry, that sounds very complicated 😛 but that’s when I would use React context, which @oconn linked above!