4 ms·
I did enjoy that article; I think it's a great overview of React's essential architecture. But I don't think it obviates the point I'm trying to make. > fundam
by notpachet 4y ago
I did enjoy that article; I think it's a great overview of React's essential architecture. But I don't think it obviates the point I'm trying to make.
> fundamentally classical OOP is message passing
OOP in its essence is about using conceptual data models as state containers. Cats, trees, input fields. Message passing is just the means by which these containers interoperate. The persistent state is the defining element.
Judged in this light, I'm arguing that the way most people write React components is more OOP than functional. The components maintain some state inherent to their nature. And I would argue that these components are still passed messages, or at least one: "render". When a component is passed the "render" message, it uses its internal state to output the appropriate DOM structure. A news widget maintains the list of headlines to display. An expanding menu holds the state for which menu items have been expanded. A form holds the errors that have been triggered from input field validation. And so on.
Thus, each component is still essentially a polymorphic implementation of an interface with a "render" method: an "instance" of a "class" that encapsulates state, even if the actual language-level class doesn't exist anymore. The mechanics are essentially the same. Since "render" was the only method being invoked on the component class, you took that lone method and promoted it to a standalone function that is invoked directly. And then you took the internal state of that class, and moved it behind the hooks API. That way, the "render" method can still access the class's internal state despite the absence of the "this" keyword. That's what I meant by misdirection. The class has just become virtualized.
Obviously it's possible for people to write React code in a way that avoids local component state. Naively we could just do prop drilling, in which case your argument that "the data flows strictly down" would actually be true (as opposed to being commingled with the data that is being stored in local component state at various levels). Or we could use Redux components, which, when written "correctly", are essentially pure functions that accept the entire application state as an argument. Et cetera.
Maybe that's actually your philosophical vision for how people should be writing React code, in a frictionless-plane-of-Platonic-ideals sort of way. Personally, mine is pretty close to the Redux model: components are just a Pachinko machine of nested functions that emit UI, and my application state lives outside of that machine, and is fed to it as an input.
But that's not how most people actually structure their React code. Instead, they continue to model their application as an aggregation of conceptual objects a la OOP. Forms. Widgets. Color pickers and the like. Each with its own persisted state. The fact that you've architected React to avoid semantic classes is orthogonal to the fact that people are still using it to implement conceptual classes.