Search code examples
reactjsuse-effectreact-tsx

UseEffect without Array always iterate, why?


Question:
WHY does the code without array always iterate in relation compare to the code with array that only execute once?

Stackblitz:

Without array:
https://stackblitz.com/edit/react-ts-9w3cgd?file=App.tsx

With array:
https://stackblitz.com/edit/react-ts-xrrvan?file=App.tsx

Thank you!


Without array

import axios from 'axios';
import * as React from 'react';
import { useEffect, useState } from 'react';
import './style.css';

export default function App() {
  const [data, setData] = useState();

  useEffect(() => {
    axios
      .get('https://jsonplaceholder.typicode.com/users')
      .then((result) => setData(result.data));

    //console.log(data);
    console.log('t');
  });

  return (
    <div>
      <h1>Hello StackBlitz!</h1>
      <p>Start editing to see some magic happen :)</p>
    </div>
  );
}

With array

import axios from 'axios';
import * as React from 'react';
import { useEffect, useState } from 'react';
import './style.css';

export default function App() {
  const [data, setData] = useState();

  useEffect(() => {
    axios
      .get('https://jsonplaceholder.typicode.com/users')
      .then((result) => setData(result.data));

    console.log(data);
    //console.log("t");
  }, []);

  return (
    <div>
      <h1>Hello StackBlitz!</h1>
      <p>Start editing to see some magic happen :)</p>
    </div>
  );
}

Solution

  • From the official React hooks documentation:

    If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array ([]) as a second argument. This tells React that your effect doesn’t depend on any values from props or state, so it never needs to re-run. This isn’t handled as a special case — it follows directly from how the dependencies array always works.

    Basically, a useEffect hook with an empty dependency array should run only once when the component mounts.

    Alternatively, if we were to not include a dependency array, the callback will run every time the component re-renders.
    Which occurs whenever there is a change in state or the state of any of it's parent components.

    With that said, it's probably better to avoid using the useEffect hook without a dependency array, since we would usually want to use it to act in a specific way upon the change of a specific state.
    Using it in such a way is valid, but not really advised.