redux app as far as i have learned, proper way to maintain your state tree is to normalize it, flaten data as far as possible and use combinereducer to create slices of the state tree.
example App that has posts and users
const rootReducer = combineReducers({
user:userReducer,
posts:postsReducer,
});
const store = createStore(rootReducer);
given posts array keep all posts init, State.posts
can look like
let initialState = {
byId:{1:{id:1,title:'post1'}},
ids:[1],
meta_data:{unread:1,old:0}
}
now if we have around 10,000 posts we would end up with state.post.ids.length === 10000
and this is fine,
Question is. since our reducer returns a new state every time it needs to update for example we need to update the meta_data.unread to be equal 0, we will return a new Post object.
return object.assign({},state,{meta_data:{unread:0,old:1}})
which will re-render all Selectors and components that consume any attribute of state.post
tree !
which sound like a problem right ?** all we wanted is updating unread counter.. why recalculate all selectors and components of Posts ?
so i had this idea that may be the state.posts should also be composed used combineReducers so that every attr. of posts should have a reducer it self.
splitting postsReducer into multiple
postsMainReducer, ==> deal with adding or removing posts
postMeta_dataReducer, ==> deal with meta_data of posts
singlePostReducer ==> Now this is dynamic !! how can i create such ??
is this correct ?, i'm adding more complexity than needed ?
-->can someone point show us a picture of an already running enterprise app state tree ? so we can learn how from it how to organize state ?
It’s important to note that a Redux store really only has a single reducer function. The store passes the current state and dispatched action to that one reducer function, and lets the reducer handle things appropriately.
Obviously, trying to handle every possible action in a single function does not scale well, simply in terms of function size and readability, so it makes sense to split the actual work into separate functions that can be called by the top-level reducer. In particular, the common suggested pattern is to have a separate sub-reducer function that is responsible for managing updates to a particular slice of state at a specific key. The combineReducers() that comes with Redux is one of the many possible ways to achieve this. It’s also highly suggested to keep your store state as flat and as normalized as possible. Ultimately, though, you are in charge of organizing your reducer logic any way you want.
However, even if you happen to have many different independent sub-reducers, and even have deeply nested state, reducer speed is unlikely to be a problem. JavaScript engines are capable of running a very large number of function calls per second, and most of your sub-reducers are probably just using a switch statement and returning the existing state by default in response to most actions.
If you actually are concerned about reducer performance, you can use a utility such as redux-ignore(https://github.com/omnidan/redux-ignore) or reduxr-scoped-reducer(https://github.com/chrisdavies/reduxr-scoped-reducer) to ensure that only certain reducers listen to specific actions. You can also use redux-log-slow-reducers(https://github.com/michaelcontento/redux-log-slow-reducers) to do some performance benchmarking.
Here are projects I most refer to -
Those are actual uses of Redux.
Here's some links:
https://github.com/andrewngu/sound-redux
https://github.com/echenley/react-news
https://github.com/paulhoughton/remember/
https://github.com/paulhoughton/mortgage/
https://github.com/benoitvallon/react-native-nw-react-calculator
https://github.com/jfurrow/flood
https://github.com/FH-Potsdam/shifted-maps
https://github.com/quirinpa/2post
https://github.com/karlguillotte/Ctfs
https://github.com/madou/gw2armory.com
which will re-render all Selectors and components that consume any attribute of state.post tree !
That is not a certainty, components do not have to re-render when unrelated properties of the store change. If your component is a PureComponent, it will not be re-rendered when the reference of the properties (values for primitive props) are equal to what they were the last render.
var foo = { a: [1, 2, 3], someCount: 1 };
var bar = Object.assign({}, foo, { someCount: 2 });
console.log(foo.a === bar.a);
// true
The returned state in the reducer will indeed be a new object, but your posts array will still be the same array (equal reference) after the assign. So React handles this nicely if you use PureComponent.
What you might stumble on next: If you are using derived data derived of the store or multiple stores in a selector, you can use reselect to memoize the result so that the reference stays the same - no re-render needed. An article describes the problem with creating new arrays for derived or empty data in each render cycle.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With