I am trying to resolve the issue with the useTransition
hook. I have a button and onClick
of it fires a function that makes an API call. The issue hee is that the isPending
from the useTransition
hook is set to false before completion of the API call.
function App() {
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const [isPending, startTransition] = useTransition();
const [data, setData] = useState(null);
useEffect(()=>{
console.log("Is Pending changed", isPending)
},[isPending])
const fetchData = async () => {
startTransition(async () => {
await delay(2000);
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1'); // Replace with your API endpoint
const result = await response.json();
setData(result);
});
};
return (
<div>
<button onClick={fetchData}>Fetch Data</button>
{isPending ? (
<p>Fetching data...</p>
) : (
data && <pre>{JSON.stringify(data, null, 2)}</pre>
)}
</div>
);
}
I expect that the useTransisition
should wait for the completion of the API call as explained in the documentation. Am I doing something wrong?
2
Answers
useTransition
didn’t support asynchronous functions before React 19. Make sure to use React 19 if you want to use asynchronous functions as your transition. Skip to the end of the answer if you are using an older React version.React 19
From the
useTransition
docs:And further down in the Troubleshooting section:
So to get your state updated after the transition, change your code to:
(Note that you don’t need the outer
async
keyword;fetchData
itself does not await anything)React 18
With older versions of React,
useTransition
didn’t support asynchronous functions. See the docs foruseTransition
in React 18:And later in the troubleshooting section:
The latter won’t help in your case, so you are left with managing the pending state yourself:
useTransition doesn’t directly depend on how long (time) a function takes to run, like a delay or waiting time. Instead, it depends on how complex or lengthy a render is. If that state update leads to expensive or complex rendering, React will show isPending as true while it’s working on that render.
here’s an example of your code that can lead to isPending to be true, i rendered the same value multiple times from the Api call so the rendering process will be more expensive