In other paradigms, it is! Our paradigm is exploring the functional take. I agree it's a bit unorthodox but we are very intentional about modeling it that way. It really has a bunch of powerful properties one might not expect.
>And aren't classes just really functions under the hood anyways?
The key difference is that in React, UI is a pure projection of current data (props/state). You're always supposed to "return" the UI. Sure a class is a function, but that function is invoked once. Its methods can be called many times, but having a pure render() method (like in class-based React) is really a class cosplaying as a function. Functions are more honest to what React is trying to be.
Relevant part from Seb's Hooks RFC comment (https://github.com/reactjs/rfcs/pull/68#issuecomment-4393148...):
> Classes may seem like the ideal thing to hold state since that's what they're designed for. However, React is more written like a declarative function that keeps getting executed over and over to simulate it being reactive. Those two things have an impedence mismatch and that keeps leaking when we think of these as classes.
>Another issue is that classes in JS merge both methods and values on the same namespace. This makes it very hard to make optimizations because sometimes methods behave like static methods and sometimes behave like values that contain functions. The Hooks pattern encourages the use of more statically resolvable calls for helper functions.
>In classes, each method has its own scope. It causes issues like us having to reinvent default props so that we can create a single shared resolved object across those. You also encourage sharing data between those methods using mutable fields on the class since the only shared thing is this. This is also problematic for concurrency.
>Another issue is just that the conceptual mental model for React is just functions calling other functions recursively. There is a lot of value to express it in those terms to help build the correct mental model.
For a concrete example of where classes as a model fails us, consider useTransition (https://react.dev/reference/react/useTransition). It lets you start rendering "in background" with a different state value. But if you get interrupted, the renders have the current value. This highlights that in React, the same piece of state can conceptually be thought of having more than a single value (kind of like being in parallel worlds). Classes don't model that well.