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

[DRAFT]: Add a Code Splitting page to the 'Recipes' section #3190

Merged
merged 8 commits into from
Dec 16, 2018

Conversation

abettadapur
Copy link
Contributor

An initial draft at a code splitting page. @markerikson Let me know your thoughts, if I need to add more sections or clarify anything in more detail

@abettadapur
Copy link
Contributor Author

#3186


## Libraries and Frameworks
There are a few good libraries out there that can help you add the above functionality automatically:
* [`redux-dynamic-reducer`](https://github.com/ioof-holdings/redux-dynamic-reducer)
Copy link
Contributor

@mpeyper mpeyper Oct 29, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, I'm the author/maintainer of redux-dynamic-reducer and while I'm stoked you want to include my library in these docs, it's unfortunately out of active development and will be deprecated soon.

Luckily, we do have a new library called redux-dynostore which supersedes it, adding more configurability and dynamic sagas support and you still get the addReducers function on the store and react bindings for ease of use.

@markerikson
Copy link
Contributor

I'll try to take a look at this in the next few days - been busy with ReactConf and work.

Copy link
Contributor

@markerikson markerikson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, looks fairly good so far. Think it ought to be ready to go in with a few tweaks, as requested.

# Code Splitting
In large web applications, it is often desirable to split up the app code into multiple JS bundles that can be loaded on-demand. This strategy, called 'code splitting', helps to increase performance of your application by reducing the size of the initial JS payload that must be fetched.

To code split with Redux, we want to be able to dynamically add reducers to the store. The default usage of Redux mandates that a single root reducer should to be passed to the `configureStore` call, which makes dynamically adding new reducers more difficult. Below, we discuss some approaches to solving this problem and reference two libraries that provide this functionality.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rephrase this a bit. It's not that "default usage mandates a single root reducer". It's that there is only one reducer, and the standard usage is to split that up into smaller functions for maintainability.

To code split with Redux, we want to be able to dynamically add reducers to the store. The default usage of Redux mandates that a single root reducer should to be passed to the `configureStore` call, which makes dynamically adding new reducers more difficult. Below, we discuss some approaches to solving this problem and reference two libraries that provide this functionality.

## Basic Principle
To dynamically add Reducers to a Redux store, there are two approaches that can be taken
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say there's only one approach - calling store.replaceReducer(). However, there may be some different ways you can handle re-creating the root reducer.

## Basic Principle
To dynamically add Reducers to a Redux store, there are two approaches that can be taken

### Using `replaceReducer`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's have a small section on what replaceReducer() is here, then move any discussion of injectReducers() or similar to an additional header section.

* [`redux-dynamic-reducer`](https://github.com/ioof-holdings/redux-dynamic-reducer)
* This library exposes the `addReducer` function on the Redux store to accomplish the behavior we described above. It also has React bindings which make it easier to add reducers within the React component lifecycle.
* [`redux-dynamic-modules`](https://github.com/Microsoft/redux-dynamic-modules)
* This library introduces the concept of a 'Redux Module', which is a bundle of Redux artifacts (reducers, middleware) that should be dynamically loaded. It also exposes a React higher-order component to load 'modules' when areas of the application come online. Additionally, it has integrations with libraries like `redux-thunk` and `redux-saga` which also help dynamically load their artifacts (thunks, sagas).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might as well toss in a link to the list of additional libs I've seen: https://github.com/markerikson/redux-ecosystem-links/blob/master/reducers.md#dynamic-reducer-injection

@netlify
Copy link

netlify bot commented Dec 16, 2018

Deploy preview for redux-docs ready!

Built with commit 5a72594

https://deploy-preview-3190--redux-docs.netlify.com

@markerikson markerikson merged commit 5350611 into reduxjs:master Dec 16, 2018
@markerikson
Copy link
Contributor

Just made those tweaks and merged this in. @abettadapur , thanks for writing this!

@raRaRa
Copy link

raRaRa commented Jan 5, 2019

It would be nice addition to know how to access the store in order to call injectReducers. E.g. if I were to write HOC or use it from some routes, how would I access injectReducers?

Some people recommend creating and then exporting the store, which other components or logic can import. What would be the recommended way? Could the docs show a small simple HOC in order to achieve this with a connected component?

@mpeyper
Copy link
Contributor

mpeyper commented Jan 5, 2019

Right now, the options are:

  1. export/import the store directly (I would not recommend this approach myself)
  2. Use the store out of the ReactReduxContext export of react-redux (not recommend as it is not a "public" API)
  3. Create your own Provider and Consumer components to access the store/inject function
  4. Use one of the libraries listed in the docs instead of rolling your own (they usually are using 2. internally but at least the unsafe access is hidden away from your code)

The problem is none of these are great solutions and I'd struggle to recommend any of them or want to endorse them by making them examples in the docs, except perhaps using a library, which I don't think there should be an example of in the redux docs.

See this issue and this PR for details and please leave feedback if you have any.

@raRaRa
Copy link

raRaRa commented Jan 10, 2019

Thanks for the detailed answer @mpeyper

One additional question, how would one inject middlewares along with reducers during run-time?

@mpeyper
Copy link
Contributor

mpeyper commented Jan 10, 2019

There's no built in way to do this and I'm not sure how I would a achieve this myself but I believe the redux-dynamic-modules library supports this.

@raRaRa
Copy link

raRaRa commented Jan 10, 2019

@mpeyper Yeah they do, but migrating to redux-dynamic-modules is not straightforward for everyone. For example, I would need to create a module for all external reducers that I'm currently using. I've opened an issue with proposal that could simplify it.

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants