Model and View in React

Is the model and view code combined into a single file in React?

In React, the traditional separation of concerns by technology (HTML for markup, CSS for styles, JavaScript for functionality) is replaced by a component-based separation of concerns. In a component, the view (markup) and logic (model) are typically defined together in the same file, promoting cohesion and encapsulation.

This means you often see JSX (which looks like HTML) and JavaScript intermingled in the same file, something like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

export default Counter;

In this Counter component, you can see that the model (the state of the counter, and the logic to update it) and the view (the JSX describing what the UI should look like) are in the same file. This makes it easy to understand how the component works, because everything related to it is in one place.

That said, as components grow more complex, it can still be beneficial to further separate concerns within the component. For example, you might extract complex logic into custom hooks, or complex markup into smaller child components.

Furthermore, it’s also common to separate CSS styles into a separate file, or to use CSS-in-JS solutions like styled-components or Emotion that co-locate styles with components. In any case, the goal is to keep related code close together to make it easier to understand and maintain.

Separation of Concern

I would not say the separation of concern is by technology. HTML is for dumb view, Javascript for UI logic and CSS for styling the UI. The View, Logic and Styling are the different concerns before library like React combined them. Is this correct?

Yes, you’re correct. The traditional separation of concerns in web development did align closely with technology: HTML for structure (view), CSS for presentation (styling), and JavaScript for behavior (logic).

However, the concern of building a cohesive and maintainable user interface component turned out to be complex enough that these boundaries sometimes blurred or created challenges.

For example, having the logic for a UI component scattered between a JavaScript file, an HTML file, and a CSS file can make it hard to understand the component as a whole. It can also be hard to ensure that changes to one file won’t inadvertently break something in another file.

React and other similar libraries or frameworks brought a shift to this paradigm. The “concern” in React is more about components. A component encapsulates its structure (JSX which is similar to HTML), presentation (CSS or CSS-in-JS), and behavior (JavaScript/React code) all in one place.

This doesn’t mean that the old separation of concerns was wrong. It’s just a different approach that has its own benefits and trade-offs. The idea is to make it easier to reason about and manage the different aspects of a component because they are all defined in the same place. So in that sense, the concept of “concern” has become more about a part of the user interface (a component) rather than a technology.