I need to fetch an API in my React project when I click on a button, but if I click again it should not redo the API call but retrieving the latest fetched data instead.
I know the hook useCallback that can memoize function. So I just put my API call inside an useCallback:
const memoizedApiResponse = React.useCallback(async () => {
console.log("fetch is called again :(");
let response = await fetch("https://api.stackexchange.com/2.2/users?order=desc&sort=reputation&site=stackoverflow");
return await response.text();
}, []);
So I just call this memoized function when I click on the button:
import React from "react";
const App = () => {
const [apiResponse, setApiResponse] = React.useState(undefined);
const memoizedApiResponse = React.useCallback(async () => {
console.log("fetch is called again :(");
let response = await fetch(
"https://api.stackexchange.com/2.2/users?order=desc&sort=reputation&site=stackoverflow"
);
return await response.text();
}, []);
const updateApiResult = async () => {
const apiResponse = await memoizedApiResponse();
setApiResponse(apiResponse);
};
return (
<div className="App">
<button onClick={updateApiResult}>fetch API</button>
<p>{apiResponse}</p>
</div>
);
};
export default App;
But sadly on each click the request is send (you can see the message in the console). Have you an idea how to memoize the request response using useCallback?
Here is a link to the codesandbox.
useCallbacksaves you from creating a function every render. It doesn't memoize the data that it might return. You will still keep calling the memoized function.apiResponsevariable is already filled inside theupdateApiResult