Effectively Using useEffect: Should We Stop Using This Hook?

Doan Duc Tin
Goalist Blog
Published in
4 min readJan 21, 2024

Since this hook is often misunderstood or misused by developers, here are some suggestions with useEffect hook in React, also providing insights on when it is best used.

Effectively Using useEffect: Should We Stop Using This Hook?

Discussing surrounding useEffect

Many articles & online discussions are against using useEffect, but for easier tracking, we are taking them into 3 groups:

🔴Concern 1: Performance issues

Some developers argue that useEffect can lead to unnecessary re-renders and impact performance. The fact that it runs after every render, can potentially cause unnecessary computations.

✨However, it’s important to note that useEffect provides optimization options, such as specifying dependencies or using the useCallback hook, to reduce the above performance issues.

🔴Concern 2: Code readability

useEffect can make code harder to understand and maintain. Why?

Because of the asynchronous nature of useEffect & handling multiple side effects, it can lead to complex code and difficult to follow

✨However, if we break down the logic into smaller, more focused useEffect hooks, (specific side effects for specific logic), the code will more cleaner, and readability can be improved.

🔴Concern 3: Pitfalls

There are potential pitfalls withuseEffect, for ex: infinite loops(a), and improper dependencies(b),...

a. An infinite loop can occur if this hook updates a state or prop that triggers a re-render, causing useEffect to be called repeatedly.

b. Improper dependencies make your application have uncontrol behavior. If dependencies are not correctly defined, useEffect may not trigger, or trigger when you don’t want, this also related to Performance issues

✨Most mistake comes from weak developers, when they can’t define or control dependencies array masterly. It is crucial to understand the dependency array and ensure it accurately with your logic.

Stop using useEffect? is using it always bad?

Absolutely NOT. With proper understanding and usage, useEffect can be a powerful and effective tool in React development.

There are a bunch of things useEffect that could help (if you implement it properly 😉), treat it as a synchronization tool.

As the official new React docs page also said:

You do need Effects to synchronize with external systems. For example, you can write an Effect that keeps a jQuery widget synchronized with the React state. You can also fetch data with Effects: for example, you can synchronize the search results with the current search query. Keep in mind that modern frameworks provide more efficient built-in data fetching mechanisms than writing Effects directly in your components.

Or more specifically, use them when you are forced to synchronize some piece of React code with some piece of the external or third-party system(*). And (*) does not offer a “react” way of doing this.

ADVICE: How to Use useEffect correctly

Understanding the Dependencies:

  • The dependency array determines when useEffect should be re-run. It should contain all the variables that useEffect relies on.
  • But also we need to carefully consider which dependencies should be included to avoid unnecessary re-renders or missed updates.
  • Avoid including dependencies that aren’t related to that logic

Effect Cleanup:

  • Cleanup functions in useEffect prevent memory leaks, ensure component unmounting correctly, and many other issues.

Common Use Cases:

  • Fetching data from an API when the component mounts are a common use case that can be handled effectively with useEffect.

✨But for some cases, it is recommended to separate the data fetching logic from the component itself. One approach is to create a custom hook specifically for fetching data -> this hook can be reused across multiple components and can encapsulate the logic for fetching and handling data.

  • Subscribing to a service or event listeners, and performing necessary cleanup operations when the component unmounts, are also suitable use cases.
  • Other: Responding to prop changes, updating component state, triggering side effects.

Testing:

  • Use testing libraries such as Enzyme to simulate component mounting and unmounting.
  • Verify that the expected side effects, like API calls or event subscriptions are triggered and cleaned up correctly.

Advanced Tips:

  • Using multiple useEffect hooks to separate concerns and improve code organization.
  • Use the useEffect hook to memoize functions used in the dependency array, optimizing performance and preventing unnecessary re-renders.

Conclusion

We should have a clear understanding withuseEffect before making any misconceptions and thinking it is useless.

By mastering useEffect and considering its advantages, developers can use its power to simplify complex scenarios and enhance the overall development process.

So, rather than dismissing it, we should explore and optimize the usage of this hook based on the specific requirements and considerations of each project. Thank you for reading.

--

--