Higher order components in React

Photo by Didssph on Unsplash
const CoolerComponent = higherOrderComponent(NotAsCoolComponent);
Photo by Anoir Chafik on Unsplash
class DogsList extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {
// "APIDataSource" is some global api data source
dogs: APIDataSource.getDogs()
};
}

componentDidMount() {
APIDataSource.addChangeListener(this.handleChange);
}

componentWillUnmount() {
APIDataSource.removeChangeListener(this.handleChange);
}

handleChange() {
// Update component state whenever the data source changes
this.setState({
dogs: APIDataSource.getDogs()
});
}

render() {
return (
<div>
{this.state.dogs.map((dog) => (
<Dog dog={dog} key={dog.id} />
))}
</div>
);
}
}
Photo by Joe Cleary on Unsplash
class CuteCat extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {
cuteCat: APIDataSource.getCuteCat(props.id)
};
}

componentDidMount() {
APIDataSource.addChangeListener(this.handleChange);
}

componentWillUnmount() {
APIDataSource.removeChangeListener(this.handleChange);
}

handleChange() {
this.setState({
cuteCat: APIDataSource.getCuteCat(this.props.id)
});
}

render() {
return <TextBlock text={this.state.cuteCat} />;
}
}
  • On mount, add a change listener to APIDataSource.
  • Inside the listener, call setState whenever the data source changes.
  • On unmount, remove the change listener.
const DogsListWithSubscription = withDataSubscription(
DogsList,
(APIDataSource) => APIDataSource.getDogs()
);

const CuteCatWithSubscription = withDataSubscription(
CuteCat,
(APIDataSource, props) => APIDataSource.getCuteCat(props.id)
);
function withDataSubscription(WrappedComponent, selectData) {
// returns another component
return class extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {
data: selectData(APIDataSource, props)
};
}

componentDidMount() {
// ... that takes care of the subscription...
APIDataSource.addChangeListener(this.handleChange);
}

componentWillUnmount() {
APIDataSource.removeChangeListener(this.handleChange);
}

handleChange() {
this.setState({
data: selectData(APIDataSource, this.props)
});
}

render() {
// Renders the wrapped component with data
// We pass through any additional props
return <WrappedComponent data={this.state.data} {...this.props} />;
}
};
}

--

--

--

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Simple knowledge about react.js

Move/Install WSl distro from C drive to another drive

'cover'

What’s the difference between function expressions and functions declarations

The Final (Book) Countdown

Meet the people who make Node.js: Colin Ihrig

JavaScript "Code Reuse" - Part 1–2 : Functional Classes

A guide to creating a nodejs npm package and publish on npm

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Mindaugas Nakrosis

Mindaugas Nakrosis

More from Medium

Create a Pagination in a React Way

React Hooks: useState

An investigative guide to React JS[DOM, Virtual DOM and JSX] Part-VII

React:- Higher Order Components: Portals