I am trying to fetch data using useEffect and load the data before page reloads but useEffect is returning empty list and is rendering component two times first before getting data and then after getting data
function App() {
const [books, setBooks] = useState([]);
useEffect(() => {
// fetch data
const dataFetch = async () => {
const data = await (await fetch("http://localhost:8000/book/")).json();
// set state when the data received
setBooks(data["message"]);
};
dataFetch();
}, []);
console.log(books);
return (
<div className="App">
<div className="data">
{books.map((book) => (
<Product key={book.isbn} book={book}></Product>
))}
</div>
<div className="buttonHolder"></div>
</div>
);
}
export default App;
CodePudding user response:
It's expected behavior. You are initializing the books
property with an empty array, and react using this value for it's initial render. When fetch
returns the data and you update the books
property with setBooks
hook. React re-renders the component due to the state value change.
Let me know if I'm missing something in your question.
If you want to add a visual indicator for this processing, you can add a loader. Something similar to below,
function App() {
...
...
return (
<div className="App">
<div className="data">
{books.length > 0 ? books.map((book) => (
<Product key={book.isbn} book={book}></Product>
)) : 'Loading books'
}
</div>
<div className="buttonHolder"></div>
</div>
);
}
export default App;