10 Steps to Convert React Class Component to React Functional Component with Hooks
After you have read about hooks and seen examples you might want to jump into your own code and convert some of your class components to functional components with hooks.
Specific changes may include the implementation of useState() to replace constructor functions and state declarations and useEffect() to replace componentDidMount() and componentDidUpdate().
Here are my 10 steps to quickly change a class component to a functional component with hooks.
- change
class NameOfComponent extends Component
to
function NameOfComponent(props){
2. remove the constructor
3. remove the render() method, keep the return
4. add const before all methods
5. remove this.state throughout the component
6. remove all references to ‘this’ throughout the component
7. Set initial state with useState(). ie…
import React, { useState } from ‘react’
Set a number
const [count, setCount] = useState(0)
Set a string
const [username, setUsername] = useState(‘’)
Set true/false
const [isOpen, setIsOpen] = useState(false)
Set an object
const [form, setValues] = useState({
id: 0,
first: ‘’,
last: ‘’,
password: ‘’,
subscribe: false
})
Set an array
const [items, setItems] = useState([])
Note: The first in the array pair is the name of the property you would like to use, the second is the name of the function you will use to update the value of the property. The parameter in useState is the initial value of the state.
8. change this.setState() … instead, call the function that you named in the previous step to update the state…
Set a number
setCount(3)
Set a string
setUsername(‘Jamie’)
Set true/false
setIsOpen(!isOpen)
Set an object
setValues({
…form,
first: ‘Jamie’,
subscribe: true
})
Set an array
setItems(items)
9. replace compentDidMount with useEffect
useEffect(() => {
fetch(‘url’)
.then(res => res.json())
.then(items => setItems(items)
.catch(console.log(err))
}, [])
Note: This function will run every time state or props are changed. Therefore, it is imperative to leave a default value as the second parameter of useEffect. Why?
In the above example, after the first render React checks useEffect, it sees that the second parameter is a blank array and it checks its memory if a blank array was stored in useEffect already. It has no blank array so it runs the function, which sets both the blank array for useEffect and whatever the function does.
Since this function updates the state, React will run this function again, but it will see the same blank array that it saved for useEffect the first time so it will not run it again. If you don’t set an array to begin with it will create a memory leak and an infinite loop of re-rendering. PS — It does not seem to have to be an empty array, it could be anything that doesn’t change.
10. replace componentDidUpdate with useEffect
const [items, setItems] = useState([])
const [id, setId] = useState(1)useEffect(() => {
if(id === '' || id === null){
return
}fetch(`url/${id}`)
.then(res => res.json())
.then(items => setItems(items)
.catch(console.log(err))
}, [id])<button onclick={e => setId(id + 1)} />
Say you are displaying items with a specific id, then the id changes for whatever reason, this useEffect function will work like componentDidUpdate(). It will check for the value of id, because that is what you passed in as the second parameter, it will see that it changed from its saved value and it will run the function again.
The state will change again so React will check the useEffect again, but it will see that it hasn’t changed so it does not run the code again.
This example courtesy of Stack Overflow.
Note: Yes, useEffect replaces both componentDidMount() and componentDidUpdate() and yes, you can use useEffect as many times as you need to in one component. See the React docs for more details about useEffect()
Conclusion
In order to learn this more thoroughly I converted a very small app from class components to one with just functional components using just the hooks in this article. The result was dramatically cleaner and easier to read code.
I can’t see any reason why I would not use hooks exclusively in the future. I look forward to creating custom hooks and using some of the more advanced features that hooks have to offer.