This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-11-08
Channels
- # aws (3)
- # bangalore-clj (1)
- # beginners (47)
- # boot (137)
- # cider (1)
- # cljs-dev (67)
- # cljsrn (7)
- # clojure (122)
- # clojure-argentina (5)
- # clojure-berlin (4)
- # clojure-czech (12)
- # clojure-france (27)
- # clojure-italy (9)
- # clojure-russia (88)
- # clojure-spec (44)
- # clojure-uk (157)
- # clojurebridge (2)
- # clojurescript (236)
- # datomic (5)
- # devcards (3)
- # dirac (23)
- # emacs (13)
- # hoplon (29)
- # incanter (1)
- # leiningen (41)
- # microservices (1)
- # off-topic (78)
- # om (145)
- # onyx (13)
- # parinfer (8)
- # pedestal (4)
- # planck (15)
- # protorepl (1)
- # re-frame (72)
- # reagent (25)
- # ring (2)
- # specter (23)
- # test-check (9)
- # untangled (106)
- # vim (8)
- # yada (1)
Hey everybody! I'm learning re-frame and I've got a conceptual question. Do you store all state in the global app state? What if a user fills out a field on a form, then navigates to another page, then navigates back (on a single-page app)? The form would still have what they typed in from before. The same goes for things like popover menus that maintain state of whether they're open or not. Does all that stuff go in the global app state? If so, how do you deal with resetting it when, for example, the user navigates to another page?
@nathan You can choose based on what makes sense for your app. Sometimes you may prefer for form inputs to stay local to the component until they are submitted, other times you may want every character typed to update app-db
https://github.com/Day8/re-com is a library which gives you these options
Thanks, I'll take a look. I imagine there could be situations where if you started out with the state being local, you might reget that later. Any experience with that? Or maybe regrets putting everything into the app db and it becoming unmanagable?
@nathan: I use namespaced handlers state a lot, it seems to keep things separate enough that it's not too hard to move back and forth from global to local state as needed. I've found that it moves quite a bit as I develop the app, but I primarily start with global state and move it local as it makes sense.
@shaun-mahood Can you explain what you mean by "namespaced handlers"?
@nathan
I put all state into the app-db in my current project.
for each panel, I have a sub-map in the db and a initialize
event which resets values in that sub-map / fetch data from the server.
@akiroz Do the panel's initialize
handlers need to know all the data their subcomponents may need then?
I'm not sure if it's a good idea but some of the components in my app actually have their own initialize/sub-map in the app-db (like a forum component)
@nathan: you can declare a handler as :my-ns/my-handler
and the namespace doesn't have to match anything - so I tend to put in namespaces that make sense for the component, and then pull them out or rename them as I figure things out further.
@shaun-mahood Oh right -- gotcha
@akiroz Ok. Yeah, I've thought about doing something like that too. Thanks for the info
@shaun-mahood @nilrecurring can you tell me, how to use reCaptcha in any registration from?
@manishkumarmdb: Sorry, I’ve never tried - you could try taking a look and see if anyone has done it using either react or reagent, and that would at least give you a starting point.
@manishkumarmdb never used reCaptcha sorry!
About the app-db, I too use the namespaced handlers style (makes things tidier, and some of the events are sent to Sente, which has namespaces events too), and was thinking lately of starting to add namespaced keywords to appdb
hi everyone, i was hoping someone could share some advice. i have a self contained, re-frame powered set of components that make up an interactive data table. it has its own state, events, handlers, etc. i have another re-frame application where i'd like to include multiple instances of the data table and dispatch events to them individually. is there a best practice for doing this?
my potential approach:
1. all events in the data table accept some ID as their first parameter: (reg-event-db :move-column (fn [db [_ table-id]))
2. in my main project i can mount the component with an id [my-data-table {:id (gensym)}]
3. when the component is mounted it would save the id to its internal state
4. the main application could then (dispatch [:move-column G__1])
5. when the table sees the event it would only update its state if it has said ID
@joshkh do your component instances keep their state separate from the re-frame app-db
?
they have their own internal state, yes. but to make matters more confusing i'd like them to be able to dispatch events in the parent application 😉
but i think that could be easily solved with some "callback" handlers that get passed to the component instances
i have a similar case of components with multiple instances and app-db
state, and instead of an instance-id
i pass a path into app-db
so your main app-db might have {:components {:component-1 {:state {}}}}
and when you mount the component you pass that in?
in that case i would pass [:components :component-1 :state]
but when the components update that path won't they be doing it in their own internal state?
the component instances don't have any internal state - only app-db
state - and the events for the component all have a path
as their first arg
(and the subscriptions too)...
iirc i couldn't see another way around it which didn't involve passing closures around and i wanted to avoid that
it worked out ok in the end - it wasn't quite the 'parameterize once and forget about it' approach i was looking for, but i wasn't unhappy
just to clarify, lets say you wanted to fire an event to just one of your components. you might do (dispatch [:highlight-column [:components :component-1] some-col-index])
your inner components all have a generic handler (reg-event-db :highlight-column [_ path some-col-index])
by the state found at path
in the app-db
that path
is all the unique value that is required 🙂
you could add something else into the state if you needed to i guess - i didn't require it
but doesn't (dispatch [:highlight-column [:components :component-1] some-col-index])
tell all component instances to evaluate highlight-column
?
component-1 component-2 and component-3 would all see the event, and component-1 would have to say "yup that's me"
ah, no - the :highlight-column
event will get handled exactly once
okay, right, so i've mounted the component three times but they are all still sharing the same re-frame event registry
yes, there is only a single event registry
okay i think i'll have to set up some initial test cases to wrap my head around it. in my situation the components have their own internal app-db, and i'll be requiring the component as a dependency. so i'm thinking in that case the tables each have their own app-db but their events get registered to my main application.
for instance, requiring https://github.com/Day8/re-frame-async-flow-fx makes the effect available to the main application
Interesting post on using Martian with re-frame - really seems to simplify things for HTTP calls - https://juxt.pro/blog/posts/advanced-martian.html
martian looks pretty sweet
agree I saw it today and it really improves the testing story for re-frame
apps
I'm especially excited for what happens to things like this as spec gains maturity
it looks like we'll just need to put pieces together for very good tooling
whoever will have time to do it first will receive lots of kudos 🙂
@mattsfrey: You should be able to change it just like a normal atom, it's found at re-frame.db/app-db
Though if I were doing it at all regularly, I'd probably set up an event handler that I can pass in some data in.
No problem, I think it's probably a good thing to forget how it's implemented most of the time - saves you from the temptation to mess with it outside of events 🙂
You have a nice dirac repl available ... then you can (dispatch [:event])
at the repl. Maybe
I guess it depends which repl - I don't think I've ever had any trouble dispatching from figwheel at least