Part of which architecture layer is React Redux?

434 Views Asked by At

I have recently read "Clean Architecture" by Bob Martin. Even though the principles he explains there apply to all languages it is harder for me to grasp those concepts around JavaScript (functional languages in general).

I have a React application where I have applied React Redux but now when I have read the book I wonder if I am not too dependent on Redux and how can I make myself more independent so that I can easily substitute Redux with any other approach (React Hooks for instance) any time I want.

Bob Martin is emphasizing on the fact that we need to be careful about architecture boundaries but I am really not sure where I can put Redux in that case?

Do I do business logic in Redux? If yes, does not this break the Clean Architecture recommendation to keep business logic independent? If I put my logic in Redux I become too dependent on it?

I have my pure view components only to display data on them them some viewModel components that handle view logic but from there I am not sure what is happening next.

2

There are 2 best solutions below

0
Mohit Gaur On

Redux should be part of the middleware.

1
René Link On

In general Redux is a state container. Redux can be used to implement the Flux architecture that facebook created for client-side applications usually implemented in React , hence the name Redux.

Redux is ususally located in the UI layer. From an architectural perspective it is then used similar to a controller and it's models in MVC. E.g. a view dispatches an action that describes what schould be done. This action is dispatched to a reducer that executes logic (like a controller) and updates the store (a kind of model). After the store changed the views rerender.

Since Redux is just a state container you could also use it in other layers. Hopefully not directly, because frameworks belong to the outer circle of the clean architecture. Thus you should create a nice abstraction and use Redux behind that abstraction (only in the implementation).

EDIT

So if I have an use case interactor class. I could call that in the reducer for example, keeping the business logic in the use case interactor class independent from the redux layer?

Yes. Let me try to visualize what I mean. You have two handle two kind of actions sync and async actions.

For sync actions the reducer takes the action argument, converts it to a request model, invokes the use case and updates the state with the response model.

+------+      +--------+       +---------+  request    +----------+
|      |      |        |       |         |  ------->   |          |
| View | ---> | Action | ----> | Reducer |             | Use Case |
|      |      |        |       |         |  response   |          |
+------+      +--------+       +---------+  <-------   +----------+
    ^                               |
    |                               | update
    |                               V
    |                          +---------+
    |   notify subscribers     |         |
    +------------------------  |  Store  | 
                               |         | 
                               +---------+                                  

For async actions the async thunk converts the action to a request model, invokes the use case and when it returns the response model it passes the response model to the reducer to update the state.

+------+      +---------+  request    +----------+
|      |      |  Async  |  ------->   |          |
| View | ---> |  Thunk  |             | Use Case |
|      |      |         |  response   |          |
+------+      +---------+  <-------   +----------+
    ^              |
    |              | 
    |              V
    |         +---------+
    |         |         |
    |         | Reducer | 
    |         |         | 
    |         +---------+     
    |              |
    |              | 
    |              V              
    |         +---------+
    |         |         |
    +- -----  |  Store  | 
              |         | 
              +---------+