Why React Hooks? Uncover Functional Patterns Beyond Class Components
This article explores the motivations behind React's Hooks API, contrasts it with the traditional Class API, delves into functional programming concepts, demonstrates practical implementations with Redux, Mixins, HOCs, custom Hooks, TypeScript type inference, codata theory, and compares React Hooks to Vue's Composition API, providing code examples and visual diagrams throughout.
Why Hooks API?
Hooks API has been visible to developers since 2018, yet many still struggle to understand its design patterns. This article examines why developers should move from the Class API to Hooks, highlights the functional programming core of Hooks, and presents alternative perspectives for learning its architecture.
TL;DR
Differences between Hooks API and Class API
Functional programming within Hooks API
Hooks API and codata/Algebra
React Hooks vs. Vue Composition API
Functional Programming
The core of Hooks API is functional programming; most APIs are expressed as functions. React’s immutable model uses JSX to map state to a virtual DOM, and state changes are triggered via setState. Redux also follows functional principles, using actions and reducers to produce new state records.
interface State {
count: number;
}
const state: State = { count: 0 };
const INCR = (state: State, payload: number = 1): State => {
return { count: state.count + payload };
};
const DECR = (state: State, payload: number = 1): State => {
return { count: state.count - payload };
};Redux’s time‑travel debugging shows the sequence of actions, but the functional approach can be hard for those unfamiliar with mathematics.
Logic Abstraction in Class API
Class components use this.state and this.setState, which works fine for simple UI updates but becomes cumbersome when abstracting reusable logic. Two common abstraction methods are Mixins and Higher‑Order Components (HOC).
Mixins
import React from "react";
import ReactDOM from "react-dom";
import { Row, Col, Button } from "antd";
const counterMixin = {
getInitialState() {
return { count: 0 };
},
incr(increment = 1) {
this.setState({ count: this.state.count + increment });
},
decr(decrement = 1) {
this.setState({ count: this.state.count - decrement });
}
};
// Deprecated since React 15.5.0
const Counter = React.createClass({
mixins: [counterMixin],
render() {
return (
<Row style={{ width: 150, textAlign: "center" }}>
<Col span={24}><h3>{this.state.count}</h3></Col>
<Col span={12}><Button onClick={() => this.incr()}>INCR</Button></Col>
<Col span={12}><Button onClick={() => this.decr()}>DECR</Button></Col>
</Row>
);
}
});Higher‑Order Component (HOC)
import React, { Component } from "react";
import ReactDOM from "react-dom";
import { Row, Col, Button } from "antd";
function CounterComponent(WrappedComponent) {
return class extends Component {
state = { count: 0 };
incr(increment = 1) { this.setState({ count: this.state.count + increment }); }
decr(decrement = 1) { this.setState({ count: this.state.count - decrement }); }
render() {
const countProps = { count: this.state.count, incr: this.incr.bind(this), decr: this.decr.bind(this) };
return <WrappedComponent {...this.props} {...countProps} />;
}
};
}
const Counter = CounterComponent((props) => {
const { count, incr, decr } = props;
return (
<Row style={{ width: 150, textAlign: "center" }}>
<Col span={24}><h3>{count}</h3></Col>
<Col span={12}><Button onClick={incr}>INCR</Button></Col>
<Col span={12}><Button onClick={decr}>DECR</Button></Col>
</Row>
);
});Hooks API
Hooks enable function components to hold state. The basic custom Hook pattern looks like:
import React, { useState } from "react";
import { Row, Col, Button } from "antd";
function useCount(initCount = 0) {
const [count, setCount] = useState(initCount);
const incr = () => setCount(count + 1);
const decr = () => setCount(count - 1);
return { count, incr, decr };
}
function Counter() {
const { count, incr, decr } = useCount();
return (
<Row style={{ width: 150, textAlign: "center" }}>
<Col span={24}><h3>{count}</h3></Col>
<Col span={12}><Button onClick={incr}>INCR</Button></Col>
<Col span={12}><Button onClick={decr}>DECR</Button></Col>
</Row>
);
}When using async/await with Hooks, the updated state may not be immediately available, unlike the Class API where awaiting this.setState yields the new value.
TypeScript‑Driven Functional Programming
Two basic function types are introduced: identity functions where input and output types match, and mapping functions where they differ. These concepts are illustrated with diagrams and a Lodash‑style data‑flow example.
Codata and Algebra
Codata is presented as a familiar mathematical concept akin to algebra. The article uses the circle area formula S = πr² to demonstrate how unknown parameters (π, r) can be treated as abstract values that become concrete only during rendering.
React Hooks vs. Vue Composition API
Vue 3 introduces a Composition API similar to React Hooks. The article shows a side‑by‑side example where Vue’s setup function returns reactive values, while React uses custom Hooks. Both approaches separate composition from rendering, but Vue’s composition runs only once, offering different performance characteristics.
import Vue from "vue";
import VueCompositionAPI, { ref } from "@vue/composition-api";
import Antd from "ant-design-vue";
Vue.use(VueCompositionAPI);
Vue.use(Antd);
const template = `
<a-row id="app">
<a-col :span="24"><h3>{{count}}</h3></a-col>
<a-col :span="12"><a-button @click="() => incr()">INCR</a-button></a-col>
<a-col :span="12"><a-button @click="() => decr()">DECR</a-button></a-col>
</a-row>`;
new Vue({
template,
setup() {
const count = ref(0);
const incr = (increment = 1) => (count.value += increment);
const decr = (decrement = 1) => (count.value -= decrement);
return { count, incr, decr };
}
}).$mount("#app");Conclusion
The article encourages readers to view Hooks not merely as a syntactic change but as a functional programming paradigm that aligns with concepts like codata and algebra. By understanding these deeper ideas, developers can reduce the steep learning curve and write more predictable, composable React code.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Taobao Frontend Technology
The frontend landscape is constantly evolving, with rapid innovations across familiar languages. Like us, your understanding of the frontend is continually refreshed. Join us on Taobao, a vibrant, all‑encompassing platform, to uncover limitless potential.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
