Redux with a large entities in a state - redux

I have a redux application. In a first load (initial state) I get data from server and put it into the store. Application have entity with name "Task". If this tasks about 500 - app work perfectly (fast). But if tasks over 2000 - I see a slow down work. This "tasks" use a differents areas.
May I optimize my application? I don't want call API for different areas because this areas use a similar "tasks".
I read about immutable.js. This is may way or not?
Thanks a lot.

The actual number of entities or JS objects in the store shouldn't matter in and of itself - it's a question of what your code is doing with those entities. If you're doing expensive transformations or filtering options every time your components re-render, then yes, an increase in the number of entities will slow things down. Also, using Immutable won't magically improve speed - it can make certain operations faster, but has overhead of its own and can be misused.
I'll point you to some resources for improving Redux performance:
My blog post Practical Redux, Part 6: Connected Lists, Forms, and Performance
A slideshow called High Performance Redux
The articles in the Redux Performance section of my React/Redux links list
The Redux FAQ entry on "scaling" Redux
The Redux FAQ entry on speeding up mapState functions

Related

Redux: Style Guide confusion on connecting more components to the store

According to Redux Style Guide, it is strongly recommended to connect more components to read data from the store.
For example, rather than just connecting a <UserList> component and reading the entire array of users, have <UserList> retrieve a list of all user IDs, render list items as <UserListItem userId={userId}>, and have <UserListItem> be connected and extract its own user entry from the store.
This, though, sounds a bit contradicting to what has been encouraged earlier in "Usage with React" section to separate presentational components from container components where the presentational components are to read data from props, not from the store.
Does this mean that:
It is best practice to keep the number of presentational components to minimum, hence increasing the number of stateful components?
Or the connected components can also be actually stateless components?
I'm a Redux maintainer, and I wrote the Style Guide page.
The short answer is that the Redux docs have been written over time, and thus some of the older docs page are out of date.
The Style Guide is our latest and current advice on how you should write your app.
We're in the process of rewriting the Redux core docs. That exact "Usage with React" page is something I intend to rewrite very soon, and when I do, I'll be dropping the terms "presentational" and "container" entirely.
I'd also encourage you to read my post Thoughts on React Hooks, Redux, and Separation of Concerns and watch my React Boston 2019 talk on Hooks, HOCs, and Tradeoffs to get some more thoughts on how hooks change the way we think about writing components.
Like everything in programming, there is a balance.
On the one hand, you have separation of concerns, making sure each block of code is focusing on one task. This can help reduce the complexity of a given component.
On the other hand, you have reduction of parameters, reducing the brittleness of your code by keeping track of fewer parameters at any given moment.
The first bullet is typically required when your state management is complex, or you have to manage server connections, and want to keep that work separate from the presentation to reduce confusion.
Redux takes care of that for you, by putting that code into the reducer. If you use the connect() higher-order component, that's exactly what you're doing: creating a component to translate state for your base presentation component. The useSelector() and useDispatch() hooks are another way of reducing the state management code in your component.
Redux stresses the second bullet because Redux's purpose is to reduce the clutter to the point that you don't need to separate your code into presentation and business logic components. Instead of passing several props back and forth, you can pass a single key, make a simple function inside your component to retrieve the data, and get on with the presentation directly.
The folks who wrote Redux also want to reassure folks that Redux is quite fast, and not to be afraid to use it generously.
My own experience is that Redux manages the business logic side of things well enough that I rarely need to create a separate wrapper component for business logic. The state code is a few lines calling hooks at the top, and that's it.
If I do have complex business logic, typically it involves deciding what state to display. That involves determining which key to use in my Redux state. So I might put all that logic into a wrapper, but the end result of the wrapper is a single key that my presentation component uses to pull the appropriate state from Redux.

Redux - keeping related reducers in sync

I'm building an Angular 1.5 app right now that I am incrementally adding Redux to. I'm coming across a problem that I'm having a hard time finding a good solution for. My application mostly deals with widgets that display data and manage the configurations that define what data is displayed in those widgets. As I add more state to Redux, the widgets reducer is getting enormous. I have broken it up into a few smaller reducers but now I'm wondering about the maintainability of a setup like this.
Essentially I worry that in the future it will be far too easy to modify one reducer or add a new action that operates on widget data and then forget to adjust all of the other reducers to account for this new aspect of the system. Or that the various ways that widget state can change via the reducers will get so complicated that it will be prohibitively difficult to make sure that I have properly adjusted all of the reducers necessary.
A lot of these reducers essentially just need to react when a widget is removed/moved/modified/whatever. I wish there was a simple catch-all way to do that in Redux like a deep watch in vanilla Angular(I know deep watchers should be avoided generally but just as an example). As I convert more of my app to use Redux, these reducers will just get more and more complex. It seems like it's a losing game. Is there some different way of approaching this problem that would be more appropriate for this problem space? Or should I just accept that some reducers are going to be enormous and that is how it has to be? Thanks for any input!
The solution to my specific problem is mostly to keep all state related to a given widget in one object so that I don't end up with redundant data management requirements. I split both state and reducers up and that caused the same logic for managing data cleanup and maintenance to be spread across different reducers. If I just split reducers up by implementing higher order reducers and keep the state in one place for one concept then this problem goes away.

Redux: Actions and reducers for every resource?

I'm currently building an application that uses a lot of 'resources' and performs the same operations on them. Every resource (customers, projects, products, invoices) has a list, edit-form, CRUD operations and more.
You can imagine a lot of code repetition. I'm thinking of generalizing into a single 'Resource' with actions like FETCH_RESOURCE, RECEIVE_RESOURCES, etc. where the resource type is a parameter. The same can be done for components.
As I am new to Redux, I'm trying to find out if this is a good or a bad idea, and if it fits with the Redux philosophy. I've looked at Redux-CRUD, but it is still generating actions and reducers for every resource.
Yes, it's very common to generalize repetitive/reusable CRUD logic like that. However, the "copies" of the logic do need some way to distinguish between dispatched actions to know which "copy" is supposed to respond.
There's examples of this kind of pattern in the Structuring Reducers - Reusing Reducer Logic section of the Redux docs, and my Redux addons catalog has large sections for existing libraries covering entity management and action/reducer generation.

Shouldn't a Redux app with immutable data run out of memory after a while?

I come from a background in embedded systems where you're really careful about memory management. With Redux especially its concept of immutability.
So let's say I'm modifying a member of an array. I have to create a new array that links to all original members plus the modified item.
I understand why using Immutability improves the speed but my question is since we essentially never remove the old copies of the objects and create new ones, Redux still keeps a reference to the old objects because of time traveling features.
Most machines these days have quite a lot of memory, but shouldn't at least in theory the Redux app crash because the tab/process runs out of memory? After a long use maybe?
No. First, Redux itself doesn't keep around old data - that's something that the Redux DevTools addon does. Second, I believe the DevTools addon has limits on how many actions it will track. Third, Javascript is a garbage-collected language, so items that are no longer referenced will be cleaned up. (Hand-waving a bit there, but that generally covers things.)
Immutable.js leverages the idea of Structural Sharing while creating new copies of collections. It implements persistent data structures and internally uses concepts like tries to implement structural sharing. So, if you created a list with 10 items, adding a new item to it will not create a new list.
Persistent data structures provide the benefits of immutability while
maintaining high performance reads and writes and present a familiar
API.
Immutable.js data structures are highly efficient on modern JavaScript VMs by
using structural sharing via hash maps tries and vector tries as
popularized by Clojure and Scala, minimizing the need to copy or cache
data.
I suggest you watch this awesome talk by Lee Bryon, Immutable.js creator

Redux: Syncing backend DB with frontend app state tree

From my experience, keeping backend DB and the frontend state tree in sync becomes a non-trivial task as the app grows more complicated.
For example, when you create a new Post in a blog, you have to create an object in the DB as well as attach a post object in your state tree (ex. inside posts reducer). It gets more complicated if the state tree is nested. If you update a comment that belongs to a post, you have to find the right post in the state tree, and find the right comment and update.
I understand why having an App State Tree is beneficial but this syncing causes too much overhead for me to truly appreciate Redux.
Q. Is there a way to do this syncing more easily?
Meteor is specifically designed to solve the problem you're mentioning.
Redux is only to manage state on the client. More precisely, its job is to hold the state needed for the ui itself.
It's often used with React where it functions as a smart place to stash anything and everything needed to render the ui. This often includes a complicated state and may include a lot of app data. It may then start to look more like a database, but databases have a number of properties that Redux lacks. Persistence comes to mind...
Meteor is a framework and Redux is not. As such, Meteor comes with an enormous amount of buy-in where Meteor decides on how to deal with a large number of issues in your app. Redux on the other hand is very permissive. It doesn't decide on what your state looks like, or how you talk to your backend, or how you render your ui.
So inasmuch as Redux allows you the freedom to decide for yourself how to deal with these issues, it also leaves you with the responsibility to do so. Redux is super tiny and you should only expect rock solid state management, and nothing more.
How much of your global app state you move to the client is entirely up to you, and how you connect it to your backend, and if this backend runs node.js+Mongo or php+mysql or lisp+text files is entirely up to you. The same can not be said when using Meteor.
With great power comes great responsibility.
I have the same question and I'm sure there's a tried-and-true correct response to this. However, I brainstormed two possible solutions:
1) add the post to the app state 'manually', then the next time a GET is requested, reconcile the state and the response (your strategy). This is a lot easier if your client state is normalized
2) do a GET immediately after the POST status is 200, and deal with the latency with an activity indicator.
The accepted answer to me , is not a fundamental explanation.

Resources