The first thing you learn about React it the class based approach:
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
which at first glace may be confusing new users. Why do we need to create a new class for every single function? Well, this is the way to let your function become part of the React Ecosystem.
There is a similar approach creating WebComponents:
class PopUpInfo extends HTMLElement {
constructor() {
super();
// write element functionality in here
...
}
}
This is similar, but different, as WebComponents feature an object oriented approach. You need to extend HTMLElement or one of its decendats to let your new Component be part of the HTML-ecosystem, but usually there is only one class for a more or less complex object that containts the whole functionallity and state management.
For React, things are different.
In the-functional-side-of-react we find a comprehensive explanation of the concepts behind react:
However, under the Object-Oriented dress, React hides a functional nature. The main constraint for a React component is to implement a render() method. The render() method returns a React element, that is the component’s markup defining its appearance. In other words, React is requiring that any component must have an output... (So)... you can think of React components as functions.
So, while react uses class based objects, it applies some constraints to the concept to use classes as first class functions.
The functional programming paradigm aims to avoid the use of the state in an application. React’s development guidelines promote the creation of stateless components, that is components not using the state property. This should grant that the output of a component only depends on its props. A stateless component looks a lot like a pure function, and indeed it is.
So, while React uses classes, should not make use of the ease of state management, that objects provide. Instead, it follows the functional approach:
This strategy corresponds to the pattern that asks the developer to use the state in the higher component in a component hierarchy. In other words, a component hierarchy should have in its root a stateful component, while its descendants should be stateless components.
So far, the concept seems to be clear, while in the react documents we find lot´s of examples where things are not that clear:
You can use stateless components inside stateful components, and vice versa.
What about Hooks
Using a functional paradigm, the most imporatant rule is to prevent side effects: Using pure functions we can isolate the state management from the functional logic.
From react -> hooks-overview we find:
The Effect Hook, useEffect, adds the ability to perform side effects from a function component
This is precisely what we find here:
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
Here we just grab a state from outside a function not as a parameter, but as an external reference.
I really tried to find the clue of this concept, but it more seems to be dirty hack than something following any paradigm. Maybe we should call this the React Hacks?
Any illumination is very welcome.
Top comments (3)
The claim made by some of React's advocates that React embraces a "Functional Approach to UI" is quite misleading - which you have now discovered for yourself. The claim is largely based on the fact that a single function (pure (stateless) or impure (stateful - with hooks)) manages the life cycle and rendering of all of it's component instances. However "components are objects".
Even before functional components there was something odd about
this.props
,this.state
and setState():I'm not even sure that statement is accurate.
React Components, Elements, and Instances:
In my understanding the correct statement should be:
The documentation is pretty clear that neither
this.props
northis.state
belong to theMyComponent
object. That's not surprising given that it is not unusual for frameworks to supply classes that have to be extended - sothis.props
andthis.state
belong to the underlyingReact.Component
object, right?My current understanding is that
this.props
andthis.state
belongs to (or is a copy of) the component instance that is currently being managed by theMyComponent
object - i.e. one singleMyComponent
object is potentially managing many component instances each with their uniqueprops
andstate
.Now stateless functional components were straightforward about this one-to-many relationship - a single function could clearly serve many component instances - but only via
props
arguments.state
couldn't be handled that way because change of state is responsible for the component (instance) being re-rendered (re-activated).To understand how hooks work I direct people to Deep dive: How do React hooks really work?. After understanding that article it becomes clear:
this.props
andthis.state
are set by React from the current component instance object (a separate object from the actual component object) before it calls a method on the component object. From the component perspective the instance data doesn't need to be actively "fetched".So component instances traded "objects" for "closures".
Quote:
i.e. "objects" and "closures" are duals of one another - one is explicit in its nature, the other is implicit.
So the only thing that really changed:
Redux's Prior Art states:
Elm Wiring:
That describes a "Functional Approach to UI" and the Elm community has come to the conclusion that components don't work in a functional UI.
React uses functions, closures, objects, and classes but it doesn't use object-oriented components or functional view functions - it's using its own brew of function managed component instances.
Another perspective I recently ran across, in particular:
The bulk of that video pits SolidJS against React.
Interestingly Soild's project founder Ryan Carniato joined EBay's Marko team in 2020.
Unlike mainstream front end frameworks Marko was designed back in 2013 to focus on server side capabilities first - and by 2017 also included client-side VDOM. Now Marko is integrating client-side reactive capabilities as an alternative to client side VDOM (Marko: Designing a UI Language) - with partial rehydration intact. Mainstream frameworks tend to "bolt on" SSR after the fact - Marko is a server side solution that "bolted on" (and integrated) client-side rendering.
For a pro-hooks examination see: React Hooks: Has React Jumped the Shark?
I really don' know why they did not used closures instead of state hooks !!!