DEV Community

Cover image for REACT -- Convert a Class Component to Functional Component with Hooks Guide w/ES6
Greg
Greg

Posted on • Edited on

REACT -- Convert a Class Component to Functional Component with Hooks Guide w/ES6

Demo
repo

In React, the class components and lifecycle methods have changed quite a bit in the last few years. Often times a developer may be handling legacy code and the newer paradigm of functional components and hooks. In this article I will use a basic example of converting a class component into a functional component with the hooks. Repo

The Rules Functional && Class Components

  • props are read-only, the same props must return the same result. Components that respect their props are called “pure”.
  • Do not mutate the state directly

The Functional vs Class:

Functional Component

  • Takes advantage of functional programming
  • A function with a traditional return statement
  • Functional Components can be stateless
  • Commonly use the useState hook that updates (overwrites) the state.
  • UseEffect takes place of the lifecycle methods

Class Component

  • Takes advantage of object oriented programming
  • Creates objects via constructor function, a built in JavaScript class method
  • The 'class', 'constructor', 'super', 'this' and 'new' keyword are needed
  • JSX is returned in the render statement
  • The render lifecycle must be managed explicitly
  • Use the setState and will merge the state
  • Method Binding

App.css

 * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: 'Courier New', Courier, monospace; background-color: rgba(125, 137, 238, 0.877); color: whitesmoke; line-height: 1.6; } ul { list-style: none; } h1, h2 { text-align: center; } .container { max-width: 768px; margin: auto; padding: 0 20px; } 
Enter fullscreen mode Exit fullscreen mode

App.js

 import './App.css'; import Dogs from './Dogs'; import Cats from './Cats'; const App = () => { return ( <div className='container'> <h1>Class to Functional</h1>  <Dogs /> <Cats /> </div>  ); }; export default App; 
Enter fullscreen mode Exit fullscreen mode

Class Component

Cats.js

 import React from 'react'; class Cats extends React.Component { render() { return( <> <h1 style={{ color: 'blue' }}>A Class Component</h1> <h1>Hello Cats</h1> </> ) } } export default Cats; 
Enter fullscreen mode Exit fullscreen mode

Functional Component w/ES6

Dogs.js

 import React from 'react'; const Dogs = () => { return ( <> <h1 style={{ color: 'red' }}>A Functional Component</h1> <h1>Hello Dogs</h1> </> ) }; export default Dogs; 
Enter fullscreen mode Exit fullscreen mode

Simple demo rendering a class and functional component

Image description

A Class Component with State, Props, and Lifecycle Method

Cats.js

 import React from 'react'; import Kittens from './Kittens'; class Cats extends React.Component { constructor() { super(); this.state = { color: 'yellow', name: 'Tartar', kittens:3 }; } componentDidMount() { alert('This componentDidMount to the DOM') } changeColor = () => { this.setState({color: "red"}); } render() { return ( <div> <h1 style={{ color: 'blue' }}>A Class Component</h1>  <h2>Hello Cats</h2>  <h2> Hello Cats. My name is {this.state.name} and I am the color {this.state.color}. </h2>  <Kittens kittens={this.state.kittens}/>  <button type='button' onClick={this.changeColor}> Class Change color </button>  </div>  ); } } export default Cats; 
Enter fullscreen mode Exit fullscreen mode

The (Kittens.js) Child Class Component

Kittens.js

 import React from 'react' class Kittens extends React.Component{ render() { return <> <h1 style={{ color: 'blue' }}>A Class Component</h1> <h2>Tartar has {this.props.kittens} kittens</h2> </> } } export default Kittens; 
Enter fullscreen mode Exit fullscreen mode

Let's Change the Class Component Cats.js to A Functional Component

I am creating new component called 'ChangeCat.js'

Side Note:

The child component called Kittens.js remained a class but still reads the props from ChangeCat.js we could go further and change the Kittens.js to functional component which would be consistent with the paradigm.

App.js

 import './App.css'; import Dogs from './Dogs'; import Cats from './Cats'; import ChangeCat from './ChangeCat'; const App = () => { return ( <div className='container'> <h1>Class to Functional</h1>  <Dogs /> <Cats /> <ChangeCat /> </div>  ); }; export default App; 
Enter fullscreen mode Exit fullscreen mode

ChangeCat.js

 import React, { useEffect, useState } from 'react'; import Kittens from './Kittens'; const ChangeCat = () => { const [catInfo, setCatInfo] = useState({ name: 'Tartar', color: 'Yellow', kittens: 3 }); useEffect(() => { alert( "This was the componentDidMount in Cats.js but now it's coming from the ChangeCat.js useEffect to the DOM" ); }, []); const handleClick = (e) => setCatInfo({ ...catInfo, color: e.target.value }); return ( <> <h1 style={{ color: 'red' }}>A Functional Component</h1>  <h2> Hello Cats. My name is {catInfo.name} and I am the color {catInfo.color} . </h2>  <Kittens kittens={catInfo.kittens} />  <button type='button' value='red' onClick={handleClick}> Functional Change Color </button>  </>  ); }; export default ChangeCat; 
Enter fullscreen mode Exit fullscreen mode

Result of Demo

Summary

Legacy code is challenging.

  • This demo compared Dogs.js (functional) and Cats.js (Class) components both can be used in React.
  • I created a class component with more complexity to include state, passing props to a child class component, and a lifecycle method.
  • I changed the Cats.js class component to a functional component called ChangeCat.js
  • Final Result is a functional component ChangeCat.js with a class component child.

Give it a try and convert the rest of the class components to functional components Repo

Links 🔗

React Docs
Demo

❤️❤️❤️

Social

Twitter
Linkedin
Portfolio
Github

🤘
Happy Coding

Top comments (0)