Closed Negan1911 closed 7 years ago
I would really like to see this merged in. In a world of modularity and bundle chunking, this is a feature that becomes more and more of a necessity.
We're attempting to create a store, using its current state as the initial state, while using the newly combined reducers, but it appears that this approach won't work
Until this got merged you could use this https://github.com/Negan1911/ng-redux-injector is just a simple factory that will hold the reducers instances to combine them later :) i hope that this got merged soon
Unfortunately, that doesn't solve my issue. Since I still am required to create a new store as a result of the merged in reducer, I have a race case scenario where the object reference change to the store causes the newly fired reducer to drop state.
Found a solution that doesn't require a modification to ngRedux.
Ultimately, the createStoreWith takes in a pure function...so the solution? Write a pure function that is dynamic. Here's how I did it:
export default class DynamicReducerLoader {
createStoreWith(reducers, middlewares, enhancers) {
if(!this.$ngReduxProvider) {
throw new Error('DynamicReducerLoader needs to have an $ngReduxProvider assigned to it prior to creating store, please add the provider prior to creating store');
} else {
this.currentReducerObject = reducers;
this.currentReducerFunction = combineReducers(reducers);
this.$ngReduxProvider.createStoreWith(this.currentReducer.bind(this), middlewares, enhancers);
}
}
currentReducer(state, action) {
return this.currentReducerFunction(state, action);
}
injectReducer(reducer) {
this.currentReducerObject = Object.assign(this.currentReducerObject, reducer);
this.currentReducerFunction = combineReducers(this.currentReducerObject);
}
}
It takes in an object defining the initial reducers (which I then call combine on). The pure function that is passed into the createStoreWith call is that of "currentReducer". This has its internal function replaced dynamically by "injectReducer". So, as reducers are injected, and recombined into a new reducer function, the currentReducer reference does not change, but the behavior of it does.
Awesome!
It's not pretty, but it works. I'd prefer that it be built into the provider, as to encapsulate the fact that I require $ngReduxProvider assigned onto the class before it can actually be used. It's yet another layer of abstraction on a layer of abstraction.
Hey all,
I actually really like this feature but wouldn't it make more sense to just add a framework-agnostic enhancer?
I created an enhancer called Paradux
that does exactly that with vanilla Redux:
function paraduxEnhancer(createStore) {
return (reducer, initialState, enhancer) => {
let reducers = [];
function addReducer(reducerFunc) {
reducers.push(reducerFunc);
var unsubscribed = false;
return function() {
if (!unsubscribed) {
reducers.splice(reducers.indexOf(reducerFunc), 1);
unsubscribed = true;
return true;
}
return false;
}
}
function enhancedReducer(reducer) {
return (state, action) => {
var newState = reducers.reduce((tempState, reducerFunc) => {
return reducerFunc(tempState, action);
}, reducer(state, action));
return newState;
};
}
const store = createStore(enhancedReducer(reducer), initialState, enhancer);
return Object.assign({}, store, { addReducer });
}
}
I can make it available as an open-source lib and it should solve all the issues without messing with ng-redux
directly.
I'm going to close this out as it is out of scope for ng-redux
.
Hi, i'm from a team of developers that hardly uses angular components, and we don't have a way to share our reducers in the same component level (we have to do a big combine of all reducers), so, taking advantage that the dependency tree runs the .config of every component and in the last time, the root .config, i developed this feature to being able to save your reducers dynamically.
This will help #75 and #80