Redux: Actions and reducers for every resource? - redux

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.

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.

What is the best normalization design for Redux store?

Should I just copy the database relationships, or are there good patterns to follow? In the Redux documentation it says that the tables should not be a lust but objects mapped by it's ids, and also have a list containing all IDs. It does not provide any example of how it can be useful though. I've seen some other random designs... What design is the most accepted in the community?
For managing normalized reducer state, use normalized-reducer. It's a higher-order-reducer that takes a schema describing the relationships, and returns a reducer, actions, and selectors that write/read according to the relationships. It also integrates easily with Normalizr and Redux Toolkit.

Is it bad to commit mutations without using actions in Vuex?

I have been using Vuex for awhile now, and I have always been following the pattern: Components use Actions to commit Mutations to mutate the Store. I thought this was the proper way to do things considering this diagram from the docs:
I came across code where people were committing mutations directly in components, and not even creating simple actions which have no purpose other than to trigger mutations. I even found several examples of this in the Vuex docs.
I figured since it's used in the docs this must be an acceptable pattern, and I was wondering if skipping Actions and directly triggering Mutations was a pattern endorsed by any other state management libraries such as Redux of Flux itself.
TLDR: Is it ok to commit mutations directly in Vuex, and if so, do other state management libraries such as Redux use a pattern like this? If so why don't they?
Just keep in mind that mutations have to be synchronous. You can commit directly in components if you (and your team) are sure is there no chance of appearing of something async. In other words, use it with simple and direct operations.
Committing only in actions as a rule adds some clarity and reliability to application's code.
I didn't used Redux, but as far as I know, some state managers have middleware.
Using mutations and action (Vuex-way) may cause a difficult maintenance into large applications.
In the future version of Vuex, mutations and actions should be merged into the one entity.
Similar discussion: https://github.com/vuejs/vuex/issues/587
Good topic here!
Actions are for more complex logic functionality specially async,
but mutations on the other hand are for changing the state .
And is totally fine to commit mutations from within your component!
(best practices are outdated by time, most of the time anyway)

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 with a large entities in a state

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

Resources