useEffect serves the same purpose as componentDidMount, componentDidUpdate, and componentWillUnmount in React classes, but unified into a single API.
The react component becomes a function and fetch gets called inside useEffect. Moreover, instead of calling this.setState I can use setData (an arbitrary function extracted from useState):
Code:
import React, { useState, useEffect } from "react"; export default function DataLoader() { const [data, setData] = useState([]); useEffect(() => { fetch("http://localhost:3001/links/") .then(response => response.json()) .then(data => setData(data)); }); return ( <div> <ul> {data.map(el => ( <li key={el.id}>{el.title}</li> ))} </ul> </div> ); }
componentDidUpdate! componentDidUpdate is a lifecycle method running every time a component gets new props, or a state change happens.
That's the trick-> If you call useEffect as I did, you would see an infinite loop. And for solving this "bug" you would need to pass an empty array as a second argument to useEffect:
Code:
useEffect(() => { fetch("http://localhost:3001/links/") >.then(response => response.json()) .then(data => setData(data)); }, []); // << super important array
If need to use async/await in useEffect then use async function with await API and then call the async function call inside useEffect.
Code:
async function getData() { const response = await fetch(url); const data = await response.json(); setData(data); } useEffect(() => { getData(); }, []);