Viktor
Viktor

Reputation: 65

Axios in React for storing response for future use

I'm trying to use the response returned by an Axios GET request for displaying it on my webpage. However, when I'm trying to store the response using the useState hook in a state variable, I'm not getting the API fetched data in my state variable.

I figure it has something to do with the async nature of Axios. Any help on how I can successfully store it in the state would greatly help. Thanks.

const [responseData, setResponseData] = useState('');

axios.get('/URL', {
   params: {
        ABC: 'abc',
        XYZ: '150'
    }
})
.then((response) => {
  console.log(response);
  setResponseData(response.data);
}, (error) => {
  console.log(error);
})

console.log('ResponseData: ' + responseData);

Upvotes: 2

Views: 263

Answers (2)

Omer
Omer

Reputation: 3486

Infinite loop -> so call with UseEffect

The problem with the code is that when setResponseData update the response, the whole component rerender and that's make axios call again and again.

My solution is call with useEffect.

export default function App() {

  const [responseData, setResponseData] = React.useState('');

  React.useEffect(() => {
    (async function () {
      await axios.get('https://cat-fact.herokuapp.com/facts', {
        params: { ABC: 'abc', XYZ: '150' }
      }).then((response) => {
        setResponseData({ response: response.data, check: Date.now() });
      }, (error) => {
        console.log(error);
      })
    })();
  }, [])

  console.log('ResponseData:', responseData);

  return (
    <div className="App">
      <span>lalla</span>
    </div>
  );
}

So now we get empty in the initial render and after fetch we get the data :)

enter image description here

Upvotes: 3

Wiktor Bednarz
Wiktor Bednarz

Reputation: 749

If you want to fetch data in a component then the best way to properly do this is via useEffect hook:

const [responseData, setResponseData] = useState('');

useEffect(() => {
    const fetchData = async () => {
        try {
            const { data } = await axios.get('/URL', {
               params: {
                    ABC: 'abc',
                    XYZ: '150'
               }
            });
            setResponseData(data);
        } catch (error) {
            console.log(error);
        }
    }
    fetchData();
}, []); // with no dependencies, this hook will run only on component mount

// Hook below serves only to confirm when data lands in your responseData state
useEffect(() => {
    if (responseData) console.log('ResponseData: ' + responseData);
}, [ responseData ]);

Upvotes: 1

Related Questions