8

I know the conventional way when using hooks is to fetch the data using the useEffect hook. But why can't I just call axios in the functional component instead of a hook and then set the data.

Basically, I am asking what is wrong with doing this:

const [users, setUsers] = useState(null);
axios.get("some api call")
  .then(res => setUsers(res.data))

Here, I do not use useEffect, what could go wrong?

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
programmer123
  • 111
  • 1
  • 2
  • 9
    It will be called every time the component renders (e.g. props change, hook state changes). Try it. That will give you an infinite loop, since every time you update the state with `getUsers`, it'll re-render, triggering another request, triggering another render, ... – cbr May 27 '20 at 19:07

3 Answers3

4

Making a request and changing the state on render like that will cause the component to re-render forever.

Every time the component renders, e.g. due to props changing or due to hooks changing, that axios.get request gets called. When it gets a response, it will update the state. Then, because the state has changed, the component re-renders, and axios.get is called again. And the state changes again, and the request is made again, forever.

cbr
  • 12,563
  • 3
  • 38
  • 63
3

Prefer useEffect(() => code... , []).

That said, you can also do it while avoiding an infinite loop but it's a very bad practice and I don't recommend it.

Yes, you will have a re-render but you won't have an infinite loop. Use useState's lazy init function.

const [users, getUsers] = useState(() => {
   axios.get("some api call")
     .then(res => getUsers(res.data))
});

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
Richard
  • 101
  • 7
  • This is a good concept. However, it would go into bottlenecks handing error with your http request – Miebaka Aug 25 '23 at 14:17
-1

Best practice is :

const [users,getUsers]= useState();
useEffect ( () => {
   axios.get("some api call")
  .then(res=>getUsers(res.data))
}, []);
S. Hesam
  • 5,266
  • 3
  • 37
  • 59