Search code examples
reactjsreduxreact-reduxclean-architecture

The separation of concerns (Clean Architecture) when using React combined with Redux


I have a problem and I'm recently researching about Clean Architecture. That is: I know that when I want to use Redux in React I will have to do like this:

ReactDOM.render(                 
   <React.StrictMode>               
       <Provider store={store}>                   
            <App />               
       </Provider>           
   </React.StrictMode>,           
document.getElementById('root') )

and then, I use useSelector and useDispatch (hooks) to select data and dispatch an action... in my react components. But, I see an problem (in my opinion). That is my react application is highly coupled with this state management tool (redux). So, if in the future, Redux becomes outdated or I don't want to use redux, I want to use Recoil, MobX or new modern state management tools, etc... Or maybe, in my app, I want to use redux combined with others (Recoil,...) to manage my app state. So, I want a loose coupling between react and redux.

But, I see very few people talking about this issue. Or maybe I was searching for the wrong keywords. Or is there something wrong with my way of thinking about 'Separation of concerns' in react and redux.

Can anyone give me a fresh look at this issue?

PS: My English is not good. I hope everyone can get my issue? Thanks a lot.


Solution

  • I had experience with both main React state managers: Redux and Mobx and struggled with the same question.

    One possible solution might be to wrap state manager logic with your custom hooks which will receive redux state and trigger actions. But if you one day decide to switch to, say, Mobx, you will see that:

    Mobx reactivity works in a different way than in redux.

    First, you will face the necessity to wrap your components in observer function which adds coupling to your components. Besides, it will take some effort to refactor your components to make it Mobx compatible because Mobx reactivity relies on value dereferencing. You can read about it in Mobx documentation. https://mobx.js.org/understanding-reactivity.html

    As i see, you can't make your components fully state-manager-agnostic if they rely on business logic. Anyway, state receiving and state updating logic will be present in your React components and it will take some time and effort to put your project on the new rails.

    The only option i see is to split React components into two types:

    1. Container component. All state-manager logic goes here. It receives application state chunks, triggers actions, and passes props to UI-components.
    2. UI-component Component that builds DOM-elements. It may have its own state, but mainly render logic is based on component props.

    This will allow you to reduce costs from changing state-manager in the future, because you can gradually rewrite your container components without worrying too much about UI.