I'm new to learning React, and I'm wondering why the following code doesn't work as expected. I thought that it would display The numbers: 0123
but it only displays 0
. I've also used the same approach with class based component, and using hooks and I still get the same result. What am I not understanding with react rendering using async code?
import React from "react";
import ReactDOM from "react-dom";
function App() {
let numbers = [0];
fetch("some.url")
.then(res => res.json())
.then(list => {
for (let n of list) {
numbers.push(n);
}
});
return <div className="App">The numbers: {numbers}</div>;
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
This means that while the component Shows is waiting for some asynchronous operation, such as fetching shows from TVMaze's API, React will render <p>loading... </p> to the DOM instead. The Shows component is then rendered only after the promises and APIs are resolved.
React Async is a promise-based library that offers a declarative API to make API calls. It provides a React component and a Hook for declarative promise resolution and data fetching. React Async is compatible with almost all the data fetching libraries and APIs, including Fetch API, Axios, and GraphQL.
With the Release of React 18, the Suspense feature has been further developed and enhanced. It fits many use cases and now it is compatible with SSR . It still can't be used for data fetching though. This feature is still in experimental mode and might make it to a further release.
Your code prints 0 because it is the value of the variable number
at render time.
You use the following code:
fetch("some.url")
.then(res => res.json())
.then(list => {
for (let n of list) {
numbers.push(n);
}
});
to get a new value asynchronously, but it won't have any effect: the component is already rendered.
If you want to refresh it, you must put your variable number in the state
and use setState()
to pass the new value.
If you want to keep with function components, you should use the brand new hooks feature, which should give you the equivalent of setState
.
You can use the useState
hook to create a piece of state that is an array, and get the list of numbers with the useEffect
hook and update the numbers when that request has finished.
Example
const { useState, useEffect } = React;
function getNumbers() {
return new Promise(resolve => {
setTimeout(() => {
resolve([1, 2, 3, 4, 5]);
}, 1000);
});
}
function App() {
const [numbers, setNumbers] = useState([0]);
useEffect(() => {
getNumbers().then(list => {
setNumbers(numbers => [...numbers, ...list]);
});
}, []);
return <div className="App">The numbers: {numbers.join(", ")}</div>;
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With