Summary:
let you perform side effects in the functional components.
it is a close replacement for componentDidMount, componentDidUpdate & componentWillUnmount from classes.
Syntax:
useEffect(() => {
},[])
Basic Example of useEffect:
Here we are displaying the current count on the website’s title using
useEffect
.With this
useEffect
, we are asking React to run the argument mentioned inside theuseEffect
whenever the component re-renders.In short, it will run after the initial render and then update after every subsequent re-render, just like
componentDidMount
andcomponentDidUpdate
in classes.
function UseEffectExample() {
const initialCount = 0
const [count, setCount] = useState(initialCount)
useEffect(() => {
document.title = `you click ${count} times`
})
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() => setCount((prevCount) => prevCount + 1)}>
Increment Count
</button>
</div>
)
}
Conditionally running side effect
We know that running the side-effect after every render can cause performance issues, so there is a way to conditionally run
useEffect
.If we extend the above example and add another
useState
to save the name whenever the user enters it in the input form, we will find thatuseEffect
is still getting triggered, which is a big performance issue.
function ConditionaluseEffect() {
const [count, setCount] = useState(0)
const [name, setName] = useState("")
useEffect(() => {
document.title = `you click ${count} times`
console.log("Updating Document Title")
}, [count])
return (
<div>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<button onClick={() => setCount((prevCount) => prevCount + 1)}>
Click {count} times
</button>
</div>
)
}
Rendering it once!
if you want to render the useEffect only once then you can add a empty array dependency at the back.
below is the example where we are going to call useEffect only once and it will be called on any re-render when the mouse will move.
function LoggingMouseMovement() {
const [x, setX] = useState(0)
const [y, setY] = useState(0)
const logMousePosition = (e) => {
console.log("mouse event")
setX(e.clientX)
setY(e.clientY)
}
useEffect(() => {
console.log("useEffect Called")
window.addEventListener("mousemove", logMousePosition)
}, [])
return (
<div>
Hooks X - {x} & Y - {y}
</div>
)
}
useEffect with cleanup
- We have
componentDidUnmount
in classes, but foruseEffect
we return a clean-up function, like we have done in the code below.
function MouseCord() {
const [x, setX] = useState(0)
const [y, setY] = useState(0)
const logMousePosition = (e) => {
console.log("mouse event")
setX(e.clientX)
setY(e.clientY)
}
useEffect(() => {
console.log("useEffect Called")
window.addEventListener("mousemove", logMousePosition)
// Code Cleanup Here!
return () => {
console.log("Component Cleanup Code")
window.removeEventListener("mousemove", logMousePosition)
}
}, [])
return (
<div>
Hooks X - {x} & Y - {y}
</div>
)
}
function MouseContainer() {
const [display, setDisplay] = useState(true)
return (
<div>
<button onClick={() => setDisplay(!display)}>Toggle Display</button>
{display ? <MouseCord /> : null}
</div>
)
}
We are creating a button to display or hide the
logMousePosition
function, but when hiding the function,useEffect
is still running theaddEventListener
, as we can see in the console.Now see the code after adding the clean-up function in which we are removing the event listener.
Fetching Data using useEffect
In this, we are fetching the post when the user types a number in the input field and then clicks the button.
So, here
useEffect
will only get triggered when you click on the button. hence saving the unnecessary API calls.
function DataFetching() {
const [post, setPost] = useState({})
const [id, setId] = useState(1)
const [idFromButtonClick, setIdFromButtonClick] = useState(1)
const handleClick = () => {
setIdFromButtonClick(id)
}
useEffect(() => {
axios
.get(`https://jsonplaceholder.typicode.com/posts/${idFromButtonClick}`)
.then((res) => {
console.log(res, "res")
setPost(res.data)
})
.catch((err) => {
console.log(err)
})
}, [idFromButtonClick])
return (
<div>
<input type="text" value={id} onChange={(e) => setId(e.target.value)} />
<button type="button" onClick={handleClick}>
Get Post
</button>
<div>{post.title}</div>
</div>
)
}
and that’s useEffect, can be overwhelming at first but constant practice of useEffect will definitely help you in becoming a good react developer. Thanks a lot for making it to the end.