React JS Higher-Order Components: A higher-order component is a function that takes a component and returns a new component. It is the advanced technique in react js for reusing component logic. These are the patterns that combine React to compositional nature. The higher-order components convert one component to another component.
Syntax of React JS HOC
Step 1: Create one React.js project.
npm install -g create-react-app create-react-app my-app cd my-app npm start
Step 2: Create one new file inside the src folder called HOC.js.
// HOC.js import React, {Component} from 'react'; export default function Hoc(HocComponent){ return class extends Component{ render(){ return ( <div> <HocComponent></HocComponent> </div> ); } } }
Now, include the following function into the App.js file.
// App.js import React, { Component } from 'react'; import Hoc from './HOC'; class App extends Component { render() { return ( <div> Higher-Order Component Tutorial </div> ) } } App = Hoc(App); export default App;
HOC Syntax Explanation
At first, we created one function which is HOC inside the hoc.js file and it accepts one argument as a component that is App in the above example.
App = Hoc(App);
Later that component was wrapped inside the react component which allows modifying and it is the primary application of HOC.
React JS Higher-Order Components Example
Let us consider one component that lists the stocks list with their price, for that we create one StockList.js component.
// StockList.js import React, { Component } from 'react'; import TableRow from './TableRow'; class StockList extends Component { constructor(props) { super(props); this.state = { stocks: [ { id: 1, name: 'TCS' }, { id: 2, name: 'Infosys' }, { id: 3, name: 'Reliance' } ] }; } tabRow(){ if(this.state.stocks instanceof Array){ return this.state.stocks.map(function(object, i){ return <TableRow obj={object} key={i} />; }) } } render() { return ( <div className="container"> <table className="table table-striped"> <thead> <tr> <td>Stock Name</td> <td>Stock Price</td> </tr> </thead> <tbody> {this.tabRow()} </tbody> </table> </div> ); } } export default StockList;
Here we are calling another component which is called as TableRows.js
// TableRow.js import React, { Component } from 'react'; class TableRow extends Component { render() { return ( <tr> <td> {this.props.obj.id} </td> <td> {this.props.obj.name} </td> </tr> ); } } export default TableRow;
Here we include the StockList.js into the App.js file.
// App.js import React, { Component } from 'react'; import StockList from './StockList'; class App extends Component { render() { return ( <div> <StockList></StockList> </div> ) } } export default App;
You have to save the file and visit the http://localhost:3000/,here you will find StockListing Table.
The second situation is the same as the first situation as mention earlier with user details of UserList.js inside the src folder.
// UserList.js import React, { Component } from 'react'; import TableRow from './TableRow'; class UserList extends Component { constructor(props) { super(props); this.state = { users: [ { id: 1, name: 'Krunal' }, { id: 2, name: 'Ankit' }, { id: 3, name: 'Rushabh' } ] }; } tabRow(){ if(this.state.users instanceof Array){ return this.state.users.map(function(object, i){ return <TableRow obj={object} key={i} />; }) } } render() { return ( <div className="container"> <table className="table table-striped"> <thead> <tr> <td>ID</td> <td>Name</td> </tr> </thead> <tbody> {this.tabRow()} </tbody> </table> </div> ); } } export default UserList;
HOC Example Explanation
Here we are just displaying the properties of stock and user with their id and name which makes HOC pass both arguments when required.
Now create one file called HOC.js inside sec directory.
// HOC.js import React, {Component} from 'react'; export default function Hoc(HocComponent, data){ return class extends Component{ constructor(props) { super(props); this.state = { data: data }; } render(){ return ( <HocComponent data={this.state.data} {...this.props} /> ); } } }
HOC Default Functions
The above file exports default function that returns a modified function with two arguments
- Component
- Data
// StockList.js import React, { Component } from 'react'; import TableRow from './TableRow'; class StockList extends Component { constructor(props) { super(props); } tabRow(){ if(this.props.data instanceof Array){ return this.props.data.map(function(object, i){ return <TableRow obj={object} key={i} />; }) } } render() { return ( <div className="container"> <table className="table table-striped"> <thead> <tr> <td>ID</td> <td>Name</td> </tr> </thead> <tbody> {this.tabRow()} </tbody> </table> </div> ); } } export default StockList;
Also, UserList.js file is like as follows
// UserList.js import React, { Component } from 'react'; import TableRow from './TableRow'; class UserList extends Component { constructor(props) { super(props); } tabRow(){ if(this.props.data instanceof Array){ return this.props.data.map(function(object, i){ return <TableRow obj={object} key={i} />; }) } } render() { return ( <div className="container"> <table className="table table-striped"> <thead> <tr> <td>ID</td> <td>Name</td> </tr> </thead> <tbody> {this.tabRow()} </tbody> </table> </div> ); } } export default UserList;
Here in App.file, we call HOC function.
// App.js import React, { Component } from 'react'; import StockList from './StockList'; import UserList from './UserList'; import Hoc from './HOC'; const StocksData = [ { id: 1, name: 'TCS' }, { id: 2, name: 'Infosys' }, { id: 3, name: 'Reliance' } ]; const UsersData = [ { id: 1, name: 'Krunal' }, { id: 2, name: 'Ankit' }, { id: 3, name: 'Rushabh' } ]; const Stocks = Hoc( StockList, StocksData ); const Users = Hoc( UserList, UsersData ); class App extends Component { render() { return ( <div> <Users></Users> </div> ) } } export default App;
In the above code, you can use render() function, where the Stocks component will be rendered.