React and Functional Programming

💡
As I was planning this post, I looked around to see if anyone else had written on this and indeed someone has in this this post, and I recommend it. I decided to add to the topic rather than restating what was said there.

The introduction of hooks in React marked a transition from class-based to functional components, sparking discussions on whether the framework was embracing functional programming (FP). But has React truly made a paradigmatic shift, or is this merely a modern rebranding of existing concepts?

Functions and Classes in JavaScript

JavaScript's use of the class and function keywords can be deceptive. The class syntax is essentially sugar for prototypes. Consider the following class:

class App extends React.Component {
  render() {
    return <div>Hello, World!</div>;
  }
}

Before ES2015, we would have defined the same class like this:

var App = function() {};

App.prototype.render = function() {
  return React.createElement('div', null, 'Hello, World!');
};

Note that the function App is Pascal-cased, the convention for classes. This echoes the same convention for defining functional components in React. A "class" in JS is actually a prototype, while a "function" doesn't automatically lend itself to FP. The syntax doesn't define the paradigm; the implementation does.

Hooks as Sugar

Hooks in functional components offer state and lifecycle management. But are hooks any more functional than state in class components? Consider this: hooks essentially move state from a class member to a variable in a closure, yet both are mutable.

// Class component
class MyClass {
  constructor() {
    this.myMutableProperty = 0;
  }
}

// Functional component with hooks
const MyClass = () => {
  const [myMutableProperty, setMyMutableProperty] = useState(0);
};

In both examples, myMutableProperty can be altered over time, deviating from the immutable nature essential to FP. This, combined with the understanding that a class is really just a function, highlights that what we get with functional components is really just a repackaging of less-than-functional concepts.

Immutable View

Don Syme categorizes the MVU (model, view, update) cycle into three typical forms in modern UI frameworks:

  • Immutable Model, Immutable View, Immutable Update
  • Immutable Model, Mutable View, Immutable Update
  • Mutable Model, Immutable View, Mutable Update

For a UI framework to align with FP principles, it should ideally operate within the first category. React manages to treat the View as immutable through its Virtual DOM but doesn't provide the same immutability guarantees for the Model and Update.

While the functional components and hooks in React offer a more modern, simplified interface, they don't necessarily push the framework closer to the functional paradigm. I hope to have stirred some thoughts around this by delving into some practical (the nature of JS classes) and some more theoretical suggestions such as immutable MVU. That said, there's no doubting React that is a great library or how important it is to the world of UI development.