On EP 002 - Multiple re-frame Instances <- overload subscribe/dispatch to accept a r/atom to use in place of app-db #741
dannyfreeman
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
An idea I've been pondering
I've been really itching for something like EP 002. So much so that for my job we are experimenting with alternative implementations of
reg-sub,reg-event-*,subscribe, anddispatchthat could operate on ratoms other than app-db. The idea would be to have a component create a ratom (ordefonceit somewhere), and pass that ratom through to it's child components. Overloaded versions ofdispatchandsubscribewould accept an optional ratom that would be used in events and subscriptions. It might be used something like this:The end goal is that we can have complex re-usable components that can exist in multiple places on a single page. And things like devcards. Those components could be written with the re-frame semantics of subs and events we know and love. And we know they won't stomp on each other's app-db state.
While working on this implementation in a separate library I came to the realization that it would be easier to implement that by forking re-frame, so I did just that.
POC For the Idea
It turned out to be relatively simple after trying to hack around it outside of the re-frame code for a couple days. Here is a link to the branch on my fork:
dannyfreeman/re-frame@master...dannyfreeman:multiple-app-dbs
That has the overloaded
subscribeanddispatchvariants. I had to add a new type offxcalledframe-fxthat provides the current ratom (I am calling this ratom aframein the code, because I've seen the name thrown around in discussions here) in order to make:db:dispatchand similar effects work on the current frame. I also added some new fx like:app-db/dispatchthat always dispatch to the global app-db, event if the current event is operating on a different frame. I've found something like that to be necessary if you pass an event vector into a component that operates on a separate frame, but needs to dispatch out of the frame back into your app's global state when something important happens.All but one test passed when I made these changes, and that test failed because I modified the subscription cache key to also include the
reagent-idof whatever frame the subscription ran on. Everything else seems to be working without any breaking changes that I can find, but I'm sure there are things I've overlooked.Example Usage
I re-worked the todo-mvc example to flex the new code a little bit, which can be seen on this branch working off my
multipel-app-dbsbranch : dannyfreeman/re-frame@multiple-app-dbs...todomvc-with-frames. The todo app makes use of a new namespace I added:re-frame.frame. The new namespace has some helper functions and react-hooks that allow for a frame to be created in a high-up-the-dom component somewhere and then accessed via ause-framehook anywhere in the component hierarchy underneath without needing to pass it as an argument to each component. It needs functional components enabled in reagent to work unfortunately, but I've yet to find other solutions outside what I consider to be pretty nasty interop with react's old context consumer api (which should work in this case if it's wanted). When functional components can't be used I personally don't mind passing a frame around as an argument to other components. Especially since that frame can also hold onto any props and swap! them in as they change.I was pretty successful with that and in running a very large re-frame app at my job against this branch without breaking anything. I am wondering what the maintainers think of this idea and if it is something they might be interested in as a solution for the mentioned EP document and long standing issues like #137
Beta Was this translation helpful? Give feedback.
All reactions