Frontend Development 11 min read

5 Ways to Reuse and Extend React Component State Logic

This article explains five approaches—Mixins, Class Inheritance, Higher‑Order Components, Render Props, and Hooks—for reusing and extending state logic in React components, comparing their advantages, drawbacks, and providing code examples to illustrate each method.

QQ Music Frontend Team
QQ Music Frontend Team
QQ Music Frontend Team
5 Ways to Reuse and Extend React Component State Logic

How can you reuse and extend React component state logic? This article presents five solutions.

Mixins

Class Inheritance

Higher‑Order Component (HOC)

Render Props

React Hooks

Below each method is introduced in detail.

1. Mixins

Mixins copy an object’s properties onto another object to achieve code reuse. They were introduced to solve reuse problems but are no longer supported in modern React because they cause hidden dependencies, tight coupling, name‑collision issues, and increased complexity.

Object.assign is a common method for copying properties, but unlike Mixins it does not copy prototype‑chain properties.

Since React has dropped Mixins, the article does not cover their usage further; refer to legacy resources for older React versions.

2. Class Inheritance

Class inheritance can reuse logic by extending a parent component, but React (and Facebook) discourage it. Inheritance makes components harder to read, forces developers to jump between parent and child code, and can overwrite lifecycle methods. Composition is preferred because it keeps components focused on a single responsibility and improves reusability, testability, and predictability.

3. Higher‑Order Component (HOC)

A HOC is a function that takes a component as an argument and returns a new component. It works like a decorator and can be implemented via inheritance inversion or props proxy.

Two implementations:

Inheritance‑based HOC (reverse inheritance)

Props‑proxy HOC (attribute proxy)

Example of an inheritance‑based HOC (simplified):

<code>export default const HOC = (WrappedComponent) => class NewComponent extends WrappedComponent {
  componentWillMount() {
    console.log('Here the original component lifecycle is modified');
  }
  render() {
    const element = super.render();
    const newProps = { ...this.props, style: { color: 'red' } };
    return React.cloneElement(element, newProps, element.props.children);
  }
};
</code>

Proxy‑based HOC example that wraps

Profile

and

Home

with a

Container

component:

<code>// app.js
import React from "react";
import ReactDOM from "react-dom";
import Profile from "./components/Profile";
import Home from "./components/Home";
import "./styles.css";

function App() {
  return (
    <div className="App">
      <Profile name="Airing" />
      <Home />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
</code>
<code>// Container.js
import React, { Component } from "react";
import "../styles.css";

export default title => WrappedComponent => class Container extends Component {
  render() {
    return (
      <div className="container">
        <header className="header">{title}</header>
        <WrappedComponent url="https://me.ursb.me" {...this.props} />
      </div>
    );
  }
};
</code>

HOC usage with

Profile

and

Home

components:

<code>// Profile.js
import React, { Component } from "react";
import WrappedComponent from "./WrappedComponent";

class Profile extends Component {
  render() {
    return (
      <>
        <p>Author: {this.props.name}</p>
        <p>Blog: {this.props.url}</p>
        <p>Component A</p>
      </>
    );
  }
}
export default WrappedComponent("Profile")(Profile);
</code>
<code>// Home.js
import React, { Component } from "react";
import WrappedComponent from "./WrappedComponent";

class Home extends Component {
  render() {
    return (
      <>
        <p>Component B</p>
      </>
    );
  }
}
export default WrappedComponent("Home")(Home);
</code>

HOCs are widely used, e.g., Redux’s

connect

function and Ant Design’s

Form.create()

are HOC implementations.

Drawbacks of HOCs include wrapper hell (deep nesting), the need to manually set

displayName

, poor TypeScript typing, ref forwarding issues, manual copying of static properties, and unintended prop leakage.

4. Render Props

Render Props pass a function as a prop to control what a component renders. The pattern is similar to React’s Context API, where a consumer receives a function that returns JSX.

<code>class App extends React.Component {
  render() {
    return (
      <ThemeProvider>
        <ThemeContext.Consumer>
          {val => <div>{val}</div>}
        </ThemeContext.Consumer>
      </ThemeProvider>
    );
  }
}
</code>

Render Props suffer from the same wrapper‑hell problem as HOCs.

5. React Hooks

Hooks solve the problems of Mixins, HOCs, and Render Props. They avoid naming conflicts, eliminate wrapper hell, and bring the benefits of functional components while providing state, lifecycle, and ref capabilities via

useState

,

useEffect

,

useRef

, etc.

The article promises a deeper dive into Hook implementations in the next installment.

reacthooksComponent ReuseHigher-Order ComponentRender Props
QQ Music Frontend Team
Written by

QQ Music Frontend Team

QQ Music Web Frontend Team

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.