Using devcards with re-frame
- Dominant language
- Clojure
- Stars
- 1.5k
- Forks
- 106
- PR merge metrics
- No merged PRs in 30d
Description
Devcards is awesome, particularly for beginners or anyone exploring Reagent or Om.
Re-frame is a great way to design large Reagent applications -- however, since there is only one app-db that holds all the state, it may not be obvious how you can use it with devcards.
I found an inelegant way to handle it -- and I'm curious if it would make sense to put it in the wiki
I also think that this pr or something like it might allow for a more idiomatic solution #97 curious of your thoughts.
### When you want to see the entire state of your re-frame db to appear in a card
require [re-frame.db :refer [app-db]] in the ns, then put that in as the db of your reagent card.
### When you want to only see some component of the state,
Def a subscription to that component of the state, and use that as the card's db
_Here's an example:_
1. Create a handler to update app-db
```
(register-handler
:demo1
(fn [_ _]
{:status "great"
:number 42}))
```
this just replaces the app-db with the map
1. dispatch that action
```
(dispatch [:demo1])
;you can deref the app-db to make sure it worked
@app-db
; should be {:status "great" :number 42}
```
if you have a card that only needs the status, register a sub for that
```
```
(register-sub
:status
(fn [db _](reaction %28:status @db%29)))
```
;; then def that subscription
(def lildb
(subscribe [:status]))
;; now you have a subset of the db you can include in a card
@lildb
;; should show "great"
(defcard-rg status-card
[:h1 (str "I'm" @lildb "today")]
lildb
{:inspect-data true})
`
```
## But wait -- there is a problem with this -- the problem being that changes to the app-db don't get reflected in the def'd subscription
--- in your devcards use that def'd subscription as the card's db, and in place of where you'd define the subscription in your component
Example
```
(defn swapper []
(let [s (subscribe [:status])]
[:div
(pr-str @s)
[:button {:on-click #(dispatch [:change-status "fantastic"])} "fantastic"]
[:button {:on-click #(dispatch [:change-status "terrible"])} "terrible"]]))
(defcard-rg status-card
[swapper]
lildb
{:inspect-data true
:history true})
```
when the dispatch buttons are clicked, the value of @s will change, but not the card's db. Why? The card's db isn't being directly altered, or called from within the card -- so if you want it to match up appropriately, you have to do things like this
```
(def lildb
(subscribe [:status]))
(defn swapper []
[:div
(pr-str @lildb)
[:button {:on-click #(dispatch [:change-status "fantastic"])} "fantastic"]
[:button {:on-click #(dispatch [:change-status "terrible"])} "terrible"]]))
```
Unfortunately, while doing that will allow you to walk the history back and forth, the history you're walking back and forth can fall out of sync with the actual app-db -- so you have to be cautious.
Is there a better way to do this?
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the app-db, subscription, and devcard examples in the issue, then read the discussion referenced by #97. Determine whether the desired outcome is wiki guidance or a more idiomatic devcards/re-frame integration; done requires an agreed approach that keeps card data and re-frame state understandable and synchronized.
Written by the indexing model from the issue text.
Assessment
- Domain
- developer-experience, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100