Skip to content

Instantly share code, notes, and snippets.

@tazsingh
Created January 25, 2016 04:02
Show Gist options
  • Save tazsingh/2eb20c2c0ab8ecd3a365 to your computer and use it in GitHub Desktop.
Save tazsingh/2eb20c2c0ab8ecd3a365 to your computer and use it in GitHub Desktop.
incremental-redux-reducers example app (not tested)
import {createStore, applyMiddleware, combineReducers} from "redux";
import thunk from "redux-thunk";
import {setupIncrementalReduxReducers, reducerStore} from "incremental-redux-reducers";
// Create the store however you like.
// For example purposes, let's apply the thunk middleware.
const createStoreWithMiddleware = applyMiddleware(
thunk
)(createStore);
// And then let's create the rootStore with a noop reducer.
const rootStore = createStoreWithMiddleware(() => {});
// This will add hooks to that rootStore that the lib will tap into.
setupIncrementalReduxReducers(rootStore);
// Alternatively, you can subscribe to the reducerStore and setup the rootStore as you like.
// As Dan Abramov mentioned, if you want to use Immutable everywhere or set up rootStore by hand, you can do that too.
// (Note this is an example, you probably wouldn't do this and the above line in a real app.)
reducerStore.subscribe(() => {
const reducerMapping = reducerStore.getState();
// Do what you please with reducerMapping.
// This is what setupIncrementalReduxReducers is doing behind the scenes.
rootStore.replaceReducer(combineReducers(reducerMapping));
});
// Dan mentioned that storing the reducers in a Redux store and using Redux actions to communicate with it
// can be removed. I tried to conceptualize that but found myself implementing global state and communicating with it.
// Redux is my preferred way to communicate with global state. But happy to field recommendations that maintain
// enough flexibility for library consumers to do what they want (i.e. what I've demo'd with the subscribe hook here)!
// Note this import is important to tell our bundler that this reducer is required by this component.
// That's how Webpack (for example) knows what to bundle for each chunk in our application.
// If multiple chunks require the same reducer, Webpack can then put it in a common chunk.
import usersReducer from "./usersReducer";
import {mapReducersToProps} from "incremental-redux-reducers";
import {connect} from "react-redux";
// I've employed this mapReducersToProps function to make it easier to map the reducer function to the state tree
// since you've already had to require the reducer function here. May as well use its tagged name value!
@connect(mapReducersToProps({
localUsers: usersReducer
}))
// Note that this is equivalent to writing:
// @connect((state) => {
// return {
// localUsers: state.users
// }
// })
export default ({localUsers}) => {
// The usual component logic with your localUsers prop.
}
import {addReducer} from "incremental-redux-reducers";
// addReducer will tell our reducerStore to assign the reducer function to the "users" key.
// Behind the scenes, this will dispatch a redux action as that's what the store responds to.
// addReducer will return the reducer function that's tagged with the name we assigned it.
export default addReducer("users", (state = [], action) => {
switch(action.type) {
// your usual reducer logic
default:
return state;
}
});
@tazsingh
Copy link
Author

I also think it's important to have a library for this as hot module reloading is a bit tricky to implement in this context. I haven't gotten there yet but have been thinking of ways to implement it for a later version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment