Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code splitting and reducer composition #346

Closed
jquense opened this issue Jul 28, 2015 · 5 comments
Closed

Code splitting and reducer composition #346

jquense opened this issue Jul 28, 2015 · 5 comments

Comments

@jquense
Copy link
Contributor

jquense commented Jul 28, 2015

Here is the simplest setup I can think of to try and get the issue across. Let me know what's confusing or unclear and I will try and clarify as much as I can. It may also be helpful for the sake of bikeshedding this particular issue to assume that I can't change the server responses.

https://gist.github.com/jquense/67ba7b7ca247b1626980

The situation is that in my app I need the siteStatusReducer state everywhere in the application. It contains a bunch of general user and app state, that is aggregated on the server. In this example we are looking at currentStatus which is the top most status in a stack of statuses. There is only one page in the app where you can actually change a status (where the siteStatusesReducer is need). Which means that the siteState.currentStatus is mostly static, unless you are on the status changing page, in which case, it needs to be updated if a new status is added that is "more recent" than the current one.

The redux suggested way of dealing with this is to combine these two reducers into a single one that manages both sets of state. That doesn't seem optimal for a few reasons.

Since siteState is used everywhere, it means that siteStatuses needs to be loaded everywhere as well, even tho it contains code that is irrelevant and unused in 90% of the application. Even accepting that as inevitable, it gets even worse when siteState contains a bunch of these aggregations; say 5 fields, analogous to currentStatus, that are only "dynamic" in a small section of the app.

I am sure there is a clever way of conditionally combining the stores if they are loaded, but I am unsure what that would look like and how it would complicate selecting that state for a view.

thanks for taking a look :)

@jquense
Copy link
Contributor Author

jquense commented Jul 28, 2015

Willing to admit that this isn't the right way to go but I did manage to solve this just by implementing waitFor for anyone who is interested.

https://gist.github.com/jquense/c9d2d82d3a7f5aa441be

Still open for a more idiomatic solution ;)

@gaearon
Copy link
Contributor

gaearon commented Jul 28, 2015

LOL that's pretty nice.

@wmertens
Copy link
Contributor

Cute waitFor 😄.

Another way to solve this is to make the hidden state explicit, namely the latest status has the highest timestamp.

So you would send actions containing statuses and timestamps as determined by the server, and your reducers would create a sorted status array if you want it, and would calculate the newest status that passed through so far (replace the currentStatus if a status has a newer timestamp). Then it is up to the server to send the most recent status as early as possible.

@wmertens
Copy link
Contributor

Upon rereading this I notice that I completely missed the point 😅.

Yeah, it's sort of a waste to have unused code loaded and doing nothing. A better example may be some huge third-party component that has lots of state and that gets loaded dynamically, with a reducer that should be processing actions too. Then indeed it would be nice if the reducer only gets added when needed.

However, reducers are generally small, so not sure this is a great concern...

On a somewhat related note, suppose you have a component with actionCreators that send some special sort of promised and require a special middleware, wouldn't it be possible to wrap dispatch in some way? Not sure if you'd be able to pass it via Context still.

If that works, perhaps a similar thing can be done with reducers, creating a wrapping store that extends the regular store with new reducers.

@gaearon
Copy link
Contributor

gaearon commented Jul 31, 2015

Let's move the discussion into #350, it consolidates similar issues.

@gaearon gaearon closed this as completed Jul 31, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants