-
Notifications
You must be signed in to change notification settings - Fork 644
Make redux drive history? #138
Comments
Hi @naw, interesting approach. It's late, so I don't have to look much at this right now, so just a few questions that jumps to mind:
|
@kjbekkelund Thank you for your initial feedback. The original commit I shared was a completely separate implementation providing a basic proof of concept by serving as a drop-in replacement within the example app. It didn't actually rewrite the existing code, so none of the tests would apply. Therefore, I have refactored my original implementation so that it is now an actual modification to the The new refactoring is here: Now to address your questions, and provide some additional clarification: All of the tests pass (most without any modification). I believe the only modifications were to accommodate the removal of The main goal is to make I believe this overall implementation yields some simplicity:
Finally, regarding your question "Is browserHistory.listen guaranteed to be synchronously called?" Is there a specific scenario you had in mind that would be a problem in this implementation, but not in the existing implementation? Thanks again. |
This is effectively the approach that redux-router takes. I haven't really been keeping track of why that project is no longer in rackt while this project is, but:
|
From the README:
Having Redux manage the state is definitely an interesting approach on paper, but dealing with the edge cases is not easy. I'm not directly involved with redux-simple-router, but I'd personally suggest working with the redux-router maintainers if you're interested in pursuing that approach. |
This fixes #108 for me, seems like a very clean approach. +1 |
Personally I see about just as much complexity here (if not more, having to manage multiple histories). You still have two flags: Additionally, there is a complex flow here: if the user presses back, it's going to trigger an event on the In fact, since everything stills works when pressing the back button, and it's going through Initially I responded similarly as @taion, because if you want only one place where all router changes come through you effectively have to write your own routing API, which is what redux-router does. And APIs are hard, and react-router has already done a ton of work on that front, so I think it's best to just leverage that. But I do like your approach (I'm assuming the I think I'd be interested exploring this approach except for one thing: they are working on react-router 2.0 and the new APIs will allow us to implement something very similar to this, but less confusing. Basically, these sort of |
We actually ended up in a very different place with 2.0 - we've explicitly taken out the ability to listen to router state, and made it clear that if you want to listen to router state, you want a component under the A few things to think about with this API:
Mostly reduces down to edge cases that I think might make this approach messier on net. |
Thanks for your response. I'm sure you already know most of this, but for sake of clarity, let me try to be a little more verbose, and please forgive me if I'm belaboring the point. There are three pieces at play here: I'm not saying this is a two sources of truth vs. one source of truth issue -- it's a question of which single piece is going to be the source of truth. In the current implementation, In my proposal, If you compare the above two paragraphs, you'll see that the overall "shape" of data flow is identical, but The premise I'm starting with is that all things being equal, it's better for There are actually two somewhat individual issues here: First, which object should be the source of truth? Second, regardless of which object is the source of truth, are there some implementation changes that would increase simplicity? So I have a a question: Disregarding complexity for a moment, which object is the preferable source of truth? In other words, assuming we could find a simple implementation to make If you feel On the other hand, if you feel that It seemed to me that my implementation with the two boolean flags and pushing everything through Granted, using a proxied history object to interface with Thanks for your reply and your patience. If you could give a me sense for how you view the "redux as the source truth" issue as a whole, that would give me a better idea how to proceed. |
@taion thanks for listing some explicit scenarios you think might cause some trouble with this implementation. It's nice to have some concrete arguments to consider. I'll plan to get back to you on your questions. |
FWIW, the You can't ask a Why do it this way? Because it completely rules out edge cases where the history that we track diverges from the history that the browser knows. And it means that if our user does something like a |
When I call Do you see a difference here in what we're saying? |
That's actually a bit counter to the design intent. The |
Router Question: "What is the current location, so that I can decide what component-tree to display?" Answer: "Whatever So the state is technically in the router, but that state is effectively being controlled by So What am I missing? |
Ignoring the transition manager for now (which potentially asynchronously does the actual route matching from the location), the difference is that the It's semantics (and it's getting late), but typically you want to think of the store-like entity as being the source of truth. |
Per discussion on #141, I think this might still be a good idea to get things working as well as possible with dev tools, in the case that users want to be able to toggle router-related actions. I don't think you'd want to use this in production – but it could dramatically simplify things for development. |
You can toggle router-related actions with the new middleware approach, no? |
Yes, but it's sort of not great. There's the lack of support for |
I made a proof of concept of this and would love to get your opinion: |
The idea behind
redux-simple-router
is to keep history in sync between redux and the router history.In my opinion, it's preferable for redux to be the source of truth for the router, rather than history to be the source of truth that is shared by the router and redux.
My idea is this:
I have a basic draft of this here:
naw@5d6c893 (update: newer draft here: naw@a47914f)
The basic implementation is:
1 Give react-router a memoryHistory object instead of the real browserHistory object.
2. The only thing that writes to memoryHistory is a redux store subscriber.
3. wrap the memoryHistory object we give to react-router so that we can intercept
push
calls so that they call a changeLocation action creator rather than writing to memoryHistory directly.4. Separately, listen to a real browserHistory object, and call the changeLocation action creator from the history listener.
Also, I'm using a slightly different approach for preventing cycles, so I believe the
locationsAreEqual
complexity is unnecessary.I've probably missed some edge cases (or perhaps I've missed something larger than that?), but I wanted to share the basic idea and get some feedback.
The text was updated successfully, but these errors were encountered: