React Hooks: useEffect and useMemo explained in-depth

Two phones clashing against each other

Share This Post

Today I’m going to explain everything about useMemo and useEffect hooks. Also, I will demonstrate how to use them and provide some useful tips and tricks which will help you in the long run.

React hooks can be a pain to understand but I’ll try to make it easy for you.

What are React Hooks?

You should already know that React follows the principle of component-based architecture and that the component is a reusable, isolated piece of code that you can mix and match with other components. Before, React developers could handle state only using class components, and additional logic for the components was supposed to be achieved via Higher Order Components (HOC), serving as a kind of component wrapper.

So, as you can already guess React Hooks changed that and with them, we can use state and other features in functional react components.

What is useEffect and what is it used for?

As the name explains, the useEffect hook is used for performing side effects in our component or a piece of code. Component rendering and side-effect logic are independent so it would be a mistake to perform side-effects directly in the body of a component which is primarily used to compute the output.

Let’s throw a glance at how the useEffect hook looks:

				
					useEffect(() => {
   // Side effect code goes here
    return () => {
        // Cleanup code goes here
    }
}, [dependencies]);
				
			

The method takes 2 arguments, but only the first one is required. If you omit the dependencies array, the side effect part will run on every re-render of the component.

In square brackets you’re supposed to type in the dependencies whose changes will trigger our side effect, meaning only then will our useEffect re-run.

If you specify an empty dependency array, useEffect will run only once (on the component mount) and if you’ve created a cleanup function, it will also run once (on the component unmount).

One important thing to note is that useEffect runs after the render function have been completed.

Now let’s take a look at an example: 

				
					import React, { useState, useEffect } from "react";
import { Button, Text, View } from "react-native";

const Example = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(`You clicked ${count} times!`);
  });

  return (
    <View>
      <Text>You clicked {count} times</Text>
      <Button
        title="Click me"
        onPress={() => {
          setCount(count + 1);
        }}
      />
    </View>
  );
};

export default Example;
				
			

If we look at this example, the useEffect hook is used to log a message to the console every time the count state is updated. In this case, the useEffect hook is run after every render because the second argument (the dependency array) is omitted.

If we add dependencies to the array, the side effect will run only when one of the dependencies has changed, like in this example:

				
					useEffect(() => {
    console.log("Effect called");
  },[count]);
				
			

In this case, the side effect will only run when the count variable changes.

Tips and tricks for useEffect

  • One thing that I’ve learned is to never add a parameter to the dependency array if you change that parameter inside the function of useEffect. That will cause an unlimited number of re-renders and your application will likely crash, so watch out for that.
  • Splitting useEffect into smaller, shorter functions that have a single purpose can prevent unintended executions (the reason for that is a very large dependency array). You may think that it’s obvious, but I guarantee you’ll miss it in longer functions with more code and variables. So do the responsible thing and divide your useEffect hooks.
  • If your useEffect subscribes to something, make sure to unsubscribe in the cleanup function. The same goes for something like a setInterval function; make sure to clear it inside the cleanup, or React will throw an error due to unpredictable changes, eventually.

What is useMemo and what’s it used for?

UseMemo is React hook that allows you to memoize the result of expensive calculations between re-renders.

Main uses of useMemo:

  • Skipping expensive recalculations
  • Skipping re-rendering of components
  • Memoizing a dependency of another Hook
  • Memoizing a function

Unlike useEffect with the second argument optional, useMemo takes two required arguments – a function that does the expensive calculation and returns its value and an array of dependencies that cause useMemo to re-run its calculation.

				
					useMemo(() => {
    const expensiveCalc = // Expensive calc algorithm goes here
    return expensiveCalc;
}, [dependencies]);
				
			

On the initial render, the value of useMemo will be the result of our calculation. On every other render, React will compare an array of dependencies and if neither has been changed, useMemo will return the value that was already calculated beforehand. Otherwise, React will re-run the calculation and return a new value.
Simply put, useMemo hook memoizes the value of the expensive calculation until one of the dependencies has changed.

Take a look at this short example:

				
					import { useMemo } from "react";
import { Text } from "react-native";

const MyComponent = ({ iterations }) => {
  const expensiveComputation = useMemo(() => {
    let result = 0;
    for (let i = 0; i < iterations; i++) {
      result += i;
    }
    return result;
  }, [iterations]);

  return (
    <Text>
      The result of the expensive computation is: {expensiveComputation}
    </Text>
  );
};

export default MyComponent;
				
			

In this example, we can see all elements that are described above. So, to repeat, expensiveComputation will only be recomputed if the iterations value changes. Use of useMemo really can help improve the performance of components by avoiding unnecessary re-renders.

Tips and tricks for useMemo

  • First of all, do not use useMemo for small irrelevant calculations because then it will use more memory and rendering time than a single piece of code. useMemo is reserved for some very complex calculations that we don’t want to run if we don’t need them so we can have the best possible performance.
  • Use useMemo with useCallback: You can use useMemo in combination with useCallback to memoize the output of a function that is passed as a prop to a child component. This can help to improve the performance of your application by avoiding unnecessary re-renders of the child component.
  • Use useMemo with React.memo: You can use useMemo in combination with React.memo to memoize the output of a functional component. This can be especially useful for optimizing the performance of components that take a long time to render.

Here is an example of how to use React.memo:

				
					import React from "react";
import { View, Text } from "react-native";

const MyComponent = ({ name }) => {
  return (
    <View>
      <Text>{name}</Text>
    </View>
  );
};

export default React.memo(MyComponent);
				
			

MyComponent in this example is a functional component that takes a name prop and renders a View with a Text element inside. We tell React to only re-render MyComponent if the name prop has changed by wrapping it in a call to React.memo. This can help to improve application performance by avoiding unnecessary re-renders of the component.

Conclusion

Both useMemo and useEffect can be extremely useful for creating efficient and maintainable React and React Native applications. However, before using them extensively, it is critical to use them with caution and carefully consider their impact on the performance of your application.

Now you know all about how to use useMemo and useEffect. I hope all of what we discussed here is loud and clear and now you can put your new knowledge to use.

Happy coding!

More To Explore

React Native vs Flutter, depiction of a boxing match
Software development

React Native vs Flutter: Choosing the right framework

While building mobile applications, development speed and app stability are very important. Two of the most popular frameworks in recent years have been React Native

Do You Want To Skyrocket Your Business?

drop us a line and keep in touch