UseEffect Rules, Best Practices, and Misuses

UseEffect Rules, Best Practices, and Misuses

ยท

3 min read

UseEffect hook is a useful tool but it should be your Last Resort, consider other alternatives first.

We will talk about useEffect Rules, best practices, and when it's overused.

Dependency Array Rules

INCLUDE :

  • Every state variable, prop, and context value is used inside the effect.

  • Reactive values: any function or variable that references any other reactive value.

  • The dependencies suggested by the ESLint rule.

DON'T INCLUDE :

  • Objects and Arrays

    React compares objects's references, so even if the new object's values are the same as the old one, it will considered different ({} !== {}). same for Arrays.

Having unnecessary dependencies in the dependencies array can cause unnecessary rerenders. Which may slow your application.

Here's how you can avoid unnecessary dependencies.

Removing unnecessary dependencies

1. Removing function dependencies

  • Move function inside useEffect.

  • If you need the function outside useEffect scope, memoize it using useCallback.

  • If the function doesn't use any reactive values, move it out of the component.

2. Removing object dependencies

Instead of including the entire object, include only the properties you need.

Example:

  • If you have an object user and you only use user.id in your effect, include only user.id in the dependency array. (check the example below)

If that doesn't work, Apply the same strategies mentioned for functions.

3. Other Strategies

If you have many related reactive values as dependencies. Try to store them in a reducer (useReducer).

PS: You don't need to include these hooks in the dependencies:

  • setState, from useState.

  • dispatch, from useReducer.

-> React guarantees them to be stable across renders.

When is UseEffect overused:

1. Fetching data

It's okay to use it in small apps. Otherwise, you should use libraries like React Query.

2. Handling user events

Use event handler functions instead.

3. Synchronizing state changes with one another

It means setting a state based on another state variable. Instead, Try to use derived state and event handlers.

There are some exceptions, let's take this example.

Imagine We wanna compute a Duration state, based on other vars (number, sets, speed, and durationBreak). In the example below. We call the calculateDuration function after each update of the state vars.

function Calculator() {
  const [number, setNumber] = useState(0);
  const [sets, setSets] = useState(3);
  const [speed, setSpeed] = useState(90);
  const [durationBreak, setDurationBreak] = useState(5);
  const [duration, setDuration] = useState(0);

  const calculateDuration = () => {
    setDuration((num, sets, spd, durBreak) => (num * sets * spd) / 60 + (sets - 1) * durBreak);
  };

  const updateNumber = (value) => {
    calculateDuration();
    setNumber(value);
  };

  const updateSets = (value) => {
    calculateDuration();
    setSets(value);
  };

  const updateSpeed = (value) => {
    calculateDuration();
    setSpeed(value);
  };

  const updateDurationBreak = (value) => {
    calculateDuration();
    setDurationBreak(value);
  };
  // render the component
}

It's working but it's redundant.

It's cleaner to have a UseEffect that will recalculate the Duration whenever one of the state variables changes, like in the code below.

function Calculator() {
  const [number, setNumber] = useState(0);
  const [sets, setSets] = useState(3);
  const [speed, setSpeed] = useState(90);
  const [durationBreak, setDurationBreak] = useState(5);
  const [duration, setDuration] = useState(0);

  useEffect(
    function () {
      setDuration((number * sets * speed) / 60 + (sets - 1) * durationBreak);
    },
    [number, sets, speed, durationBreak]
  );
   // render the component
}

Conclusion

UseEffect is a powerful hook for managing side effects in React. Understanding when and how to use it is a must.

Those were my notes from Jonas's react course.

If you have any thoughts or questions, feel free to reach out to me on Twitter or LinkedIn.

ย