DEV Community

Cover image for Separation of concerns in React and React Native.
Sathish Kumar N
Sathish Kumar N

Posted on • Updated on

Separation of concerns in React and React Native.

As developers, we all know the feeling of adding new feature with screen full of codes which seems to go on forever. Whether you're a seasoned developer or just getting started, this post will give you a deeper understanding of the power of separation of concerns and how you can apply it to your own web and mobile development work.

Separation of concerns is a practice of divide our code into more maintainable, reusable and testable separate sections or modules which is responsible for one single purpose, specific task.

The Power of Separation of Concerns

  1. Increase Cohesion

  2. Reduce Coupling

  3. Clean and Maintainable.

  4. Reusable across different parts of the application.

  5. Easy to test.

  6. Better code quality at all levels.

Overall, by using the separation of concerns in React, we can increase cohesion and reduce coupling, leading to a more maintainable and scalable codebase.

Separation of Concerns in Action: Real-World Examples from Web Development

Let's take an example of good old-fashioned Todo app.

While this simple Todo app may be easy to maintain in its current state, more complex logic and additional requirements could quickly make the codebase difficult to manage.

In such cases, even the most seasoned developers might hesitate to make changes, fearing that they'll break something or unknowingly introduce bugs.

Solution

As our render function grows in size and complexity, it can become difficult to read and maintain. In order to improve code clarity and separation of concerns, it's a good idea to split the render function into separate UI elements.

By doing so, we can compartmentalise different aspects of the UI and more easily make changes or updates. Additionally, this can lead to better code reusability and testability, as each UI element can be individually tested and reused in other components as needed.

Image description

We will explore some strategies and best practices for managing a complex app and keeping your codebase clean, maintainable, and bug-free.

1. Separate JSX File.

Responsible for for displaying UI elements only.

We will create a Todo.jsx file that exclusively contains JSX elements.

Image description

Consider creating a separate function specifically for rendering the input, button and list elements,

Input element

Image description

Button Element

Image description

List Element

Image description

We will split the todo item into separate component for improve maintainability.

Todo Item

Image description

2. Custom Hooks

Responsible for handling Logics, UI events and callbacks.

For handling Logics, UI Events and Callbacks related to Todo.jsx, We will create a custom hook called useTodo.js

This will improved the maintainability and readability.

We can now test each function in isolation with any Node.js testing library, regardless of whether it supports React components or not.

Let's Add State Logic,

Image description

If this component only has a few states, it can be managed within the custom hook itself. However, if the number of states increases, it's best to create a separate file for a reducer and handle the states in that file to avoid cluttering the custom hook.

Let's Add UI Events and Callbacks,

Image description

If a component only has a few lines of JS code, it may not be necessary to separate the logic as it can be easily managed within the same file.

3. Utils File

Responsible for logic and helper functions as needed.

To keep our custom hooks clean and organised, we can add any additional logic or helper functions in the todoUtils.js utils file.

Image description

4. Reducer File

Responsible for managing and manipulating data (if necessary).

Discover how combining the power of useReducer with the efficiency of Redux Toolkit can help you take your React app's performance and code quality to the next level. Check out our latest blog!

5. Api File

Responsible for connecting to servers.

Separating our API calls into separate files can make our code more modular, allowing you to easily add or remove functionality without affecting other parts of your application.

This can also make it easier to write unit tests for our code. We can add test each component individually, without having to worry about the larger application as a whole.

We can use Redux toolkit - RTK Query's createApi is a powerful feature of the React-Redux Toolkit that provides more number of benefits.

6. Style File

Responsible for styling JSX elements.

When our styles are organised into separate files based on functionality, it is easier to follow the flow of our application and understand how different parts of our code interact with each other.

For React, we can add css, scss and css modules in this styles file.

For React Native, we can add component styles here instead of using in component file itself.

Finally, our todo app will look like this,

Key Learnings: Implementing Separation of Concern

By separating concerns in this way, we have made testing our code much more manageable. Instead of testing the entire component's code, we can now test each function in isolation with any Node.js testing library, regardless of whether it supports React components or not.

This also means that we can reuse these functions in other parts of our application, making them more flexible and maintainable.

By keeping our framework-specific code in the component and the hook, and our business logic in separate functions, we have created a more modular and extensible codebase that is easier to reason about and maintain.

If a component only has a few lines of JS code, it may not be necessary to separate the logic as it can be easily managed within the same file.

You can check this entire code in Code sandbox and GitHub.

Please give your feedback and questions on comments section.

Happy Coding!!

Top comments (0)