Simply put, Higher-Order Component(HOC) is a function that takes in a component and returns a new component.
When do we need a Higher Order Component?
While developing React applications, we might develop components that are quite similar to each other with minute differences.
In most cases, developing similar components might not be an issue but, while developing larger applications we need to keep our code DRY, therefore, we want an abstraction that allows us to define this logic in a single place and share it across components.
HOC allows us to create that abstraction.
Example of a HOC: Consider the following components having similar functionality.
The following component displays the list of articles: // "GlobalDataSource" is some global data source class ArticlesList extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = { articles: GlobalDataSource.getArticles(), }; } componentDidMount() { // Listens to the changes added GlobalDataSource.addChangeListener(this.handleChange); } componentWillUnmount() { // Listens to the changes removed GlobalDataSource.removeChangeListener(this.handleChange); } handleChange() { // States gets Update whenver data source changes this.setState({ articles: GlobalDataSource.getArticles(), }); } render() { return ( <div> {this.state.articles.map((article) => ( <ArticleData article={article} key={article.id} /> ))} </div> ); } } The following component displays the list of users: // "GlobalDataSource" is some global data source class UsersList extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = { users: GlobalDataSource.getUsers(), }; } componentDidMount() { // Listens to the changes added GlobalDataSource.addChangeListener(this.handleChange); } componentWillUnmount() { // Listens to the changes removed GlobalDataSource.removeChangeListener(this.handleChange); } handleChange() { // States gets Update whenver data source changes this.setState({ users: GlobalDataSource.getUsers(), }); } render() { return ( <div> {this.state.users.map((user) => ( <UserData user={user} key={user.id} /> ))} </div> ); } } Notice the above components, both have similar functionality but, they are calling different methods to an API endpoint.
Let’s create a Higher Order Component to create an abstraction: // Higher Order Component which takes a component // as input and returns another component // "GlobalDataSource" is some global data source function HOC(WrappedComponent, selectData) { return class extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = { data: selectData(GlobalDataSource, props), }; } componentDidMount() { // Listens to the changes added GlobalDataSource.addChangeListener(this.handleChange); } componentWillUnmount() { // Listens to the changes removed GlobalDataSource.removeChangeListener(this.handleChange); } handleChange() { this.setState({ data: selectData(GlobalDataSource, this.props), }); } render() { // Rendering the wrapped component with the latest data data return <WrappedComponent data={this.state.data} {...this.props} />; } }; } We know HOC is a function that takes in a component and returns a component.
In the code above, we have created a function called HOC which returns a component and performs functionality that can be shared across both the ArticlesList component and UsersList Component.
The second parameter in the HOC function is the function that calls the method on the API endpoint.
We have reduced the duplicated code of the componentDidUpdate and componentDidMount functions.
Using the concept of Higher-Order Components, we can now render the ArticlesList and UsersList components in the following way: const ArticlesListWithHOC = HOC(ArticlesList, (GlobalDataSource) => GlobalDataSource.getArticles()); const UsersListWithHOC = HOC(UsersList, (GlobalDataSource) => GlobalDataSource.getUsers()); Remember, we are not trying to change the functionality of each component, we are trying to share a single functionality across multiple components using HOC.
Simply put, Higher-Order Component(HOC) is a function that takes in a component and returns a new component.
When do we need a Higher Order Component?
While developing React applications, we might dev...