![cover](/_app/immutable/assets/space_cover.h45XWM0x.jpg)
Demystifying React useEffect
Published at May 12, 2020
Here’s a quick explaination on React’s useEffect! My assumption is you are familiar with how class components work in React, so I’ll explain what the hooks equivalents are 🚀
Let’s get straight to it
useEffect vs componentDidMount
In React, the two most common lifecycle methods used are componentDidMount
and componentDidUpdate
. The latter is used mostly when your prop changes from the parent, and the child has to update in response.
The former is mostly for making external HTTP requests to a server to fetch data. For instance, you can fetch data from jsonplaceholder (a free API tool) like so:
import React from 'React';
class App extends React {
componentDidMount{
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => console.log(json))
}
}
}
This grabs data once the component mounts, and log it to the console (suprise!). So, what’s the equivalent in hooks?
Let’s step back for a moment, before the world of hooks came about. We had (and still have) another way of writing components in React. “functional” or stateless components like these:
const Footer = () => {
return (
<div>
<h1>Dude, I'm a footer<h1>
</div>
)
}
export default Footer
You could pass props, and in these props callback functions to modify the parent’s state.
const Footer = (props) => {
return (
<div>
<h1>{props.title}</h1>
<button onClick={props.callback}>Callback Function</button>
</div>
)
}
export default Footer
When you write in React Hooks, you are writing components in a functional-esque style like the above, but combining it with the power of class-like components via “hooks”.
Let’s go back to our original example with componentDidMount
. Here’s how you’d write this with hooks
import {useEffect} from 'React';
const App = (props) => {
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => console.log(json))
}
},[]);
}
This runs one time. We specify at the end []
to indicate it runs only one time
useEffect vs ComponentDidUpdate
The last argument indicated above []
is actually what controls how often the useEffect
code gets runned. So how does this translate to componentDidUpdate
?
One of the common use cases of componentDidUpdate
is doing a side-effect from a changed prop from the parent component.
Here’s an example:
import react from "React";
class App extends React {
componentDidUpdate(previousProps){
if(previousProps.visible !== this.props.visible) {
// execute changes
}
}
What we’re doing here is checking if our current incoming this.props
has changed from the previousProps
. If prop.visible
did change,
go execute code changes.
What’s the equivalent of this in hooks?
import {useEffect} from "React";
const App = (props) => {
useEffect(()=> {
// execute changes
}, [props.visible]);
}
[props.visible]
acts as a watcher of sorts, to specify when useEffect
should run. In this case, only when props.visible
has been modified
useEffect vs componentDidMount/componentDidUpdate
Just as a last ending note, if you don’t specify anything in the last argument in useEffect
import {useEffect} from "React";
const App = (props) => {
useEffect(()=> {
// this is basically componentDidMount + componentDidUpdate combined
// it executes once on componentDidMount, and any when any state variables update from useState
});
}
you’ve essentially combined componentDidMount
and componentDidUpdate
all in one.