user13709264
user13709264

Reputation: 47

React: Stop hook from being called every re-rendering?

Somewhat new to React and hooks in React. I have a component that calls a communications hook inside of which a call to an API is made with AXIOS and then the JSON response is fed back to the component. The issue I'm having is the component is calling the hook like six times in a row, four of which of course come back with undefined data and then another two times which returns the expected JSON (the same both of those two times).

I did a quick console.log to double check if it was indeed the component calling the hook mulitple times or it was happening inside the hook, and it is the component.

How do I go about only have the hook called only once on demand and not multiple times like it is? Here's the part in question (not including the rest of the code in the widget because it doesn't pertain):

export default function TestWidget() {

//Fetch data from communicator
console.log("called");
const getJSONData = useCommunicatorAPI('https://jsonplaceholder.typicode.com/todos/1');

//Breakdown passed data
const {lastName, alertList, warningList} = getJSONData;

return (          
            <h1 id="welcomeTitle">Welcome {lastName}!</h1>

     );

}


export const useCommunicatorAPI = (requestAPI, requestData) => {

const [{ data, loading, error }, refetch] = useAxios('https://jsonplaceholder.typicode.com/todos/1', []);
console.log("data in Communicator:", data);

   return {data};
 }

Upvotes: 3

Views: 1899

Answers (3)

Special Character
Special Character

Reputation: 2359

I would use the useEffect hook to do this on mount and whenever any dependencies of the request change (like if the url changed).

Here is what you will want to look at for useEffect

Here is what it might look like:

const [jsonData, setJsonData] = React.useState({})
const url = ...whatver the url is
React.useEffect(() => {
  const doFetch = async () => {
    const jsonData = await callAxios(url, []);;
    setJsonData(jsonData)
  }
  doFetch();
}, [url])
...use jsonData from the useState

With the above example, the fetch will happen on mount and if the url changes.

Upvotes: 1

Rodrigue Badini
Rodrigue Badini

Reputation: 33

Try creating a function with async/await where you fetch the data.

Here can you learn about it: https://javascript.info/async-await

Upvotes: 0

Joe Lloyd
Joe Lloyd

Reputation: 22323

Why not just use the hook directly?

export default function TestWidget() {
 const [{ data, loading, error }, refetch] = 
useAxios('https://jsonplaceholder.typicode.com/todos/1', []);

  return (<h1 id="welcomeTitle">Welcome {lastName}!</h1>);
}

the empty array [] makes the hook fire once when called

Upvotes: 1

Related Questions