Hello Redux!
I have to say this is a great way to manage your state for your application. But I have a few questions that I cannot seem to find an answer to anywhere on the internet.
Handling your state across multiple routes, meaning:
I have my state, looks something like this:
{
user: {},
routing: {}
}
And I have a few different pages, meaning that it adds (for example) todos which only matters in the /todo route. How is something like this handled? Or do I not even include this in redux. I was thinking I could add an object for every route, but that would get messy, quickly. Unless this is the suggested route to take?
I am looking for the correct "redux" answer to this. Would I just not include those values in Redux, or would I create only for every route and just nest the values as I went? Anything is helpful at this point, because I'm running out of an ideas for this.
Thank you everyone!
-- Posted in StackOverflow, but if anyone else is wondering this please let me know. Thanks.
@mikehuebner Please post questions on stackoverflow.
Keep all your data in the store regardless of current route. This way it's cached as you go between routes. You can use any routing solution including vanilla HTML pushState API, React Router, redux-simple-router, or anything else.
@gaearon
Actually it's an interesting topic : How to design your state tree?
In most cases, different routes means different resources to show, there are few data need to be shared, like the login info.
And besides the domain data like User, there're lot of UI state which is really page specified, like the open status of a tab or a popup. I would really like to manage them by redux, but how to design the reducer tree ? Now it looks like :
{
todos,
user,
pageA: {isTabOpen, isPopupActive}
}
I'm not sure because this kind of mixed way looks weird and might be a messy when you have bunch of pages.
We don't have this kind of problem in elm architechture cause we define and compose both update and view at the same time, the update function only care about the view it served, not domain object. So in different pages, you will have different update function naturally.
But in redux the store looks like very different, you need to define and compose the reducer tree separately.
I'm still confused about that and not sure what's the suggested way to do it.
@kpaxqin I think it's OK to have both domain and UI state in the store. This allows to reason about what data has or hasn't been available when certain UI is being displayed. The routing state should be there, too, to make sure the navigation is controlled by the same system of state+action.
And I can't fully agree with that the state is very specific to a route. Some connected components may appear on different routes.
You can listen for the route change events, and when the route isn't part of your state domain, reset the state's tree to null (assuming something like combineReducers)...
Routing changes are something that seems like it could use another parameter beyond a typical reducer, similar to redux-thunk, but for route changes.
@gaearon
Sorry for reopening an old issue like that, but don't you think keeping the data in the state regardless of a route can be bothersome sometimes?
Example:
Route: /user/id -> this route displays the user's page has the state: { username, shoppingCartId }
Route: /user/id/cart/shoppingCartId -> this route displays the cart and has the state: { username, shoppingCartId, products: [p1, p2, p3] }
Route: /user/id/cart/shoppingCartId/product/productId -> this route displays the product in the cart and has the state { username, shoppingCartId, products: [p1, p2, p3], p1: {...productData} }
If you updated the state based on the context (route) you could have those much simpler states:
/user/id : { username, shoppingCartId }
/user/id/cart/shoppingCartId : { products: [p1, p2, p3] }
/user/id/cart/shoppingCartId/product/productId : { ...productData }
I've been debating with this idea for quite some time and would really like your input about such a situation.
Most helpful comment
Keep all your data in the store regardless of current route. This way it's cached as you go between routes. You can use any routing solution including vanilla HTML pushState API, React Router, redux-simple-router, or anything else.