FAQ: The Effect Hook - Control When Effects Are Called

This community-built FAQ covers the “Control When Effects Are Called” exercise from the lesson “The Effect Hook”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Learn React

FAQs on the exercise Control When Effects Are Called

There are currently no frequently asked questions associated with this exercise – that’s where you come in! You can contribute to this section by offering your own questions, answers, or clarifications on this exercise. Ask or answer a question by clicking reply (reply) below.

If you’ve had an “aha” moment about the concepts, formatting, syntax, or anything else with this exercise, consider sharing those insights! Teaching others and answering their questions is one of the best ways to learn and stay sharp.

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!
You can also find further discussion and get answers to your questions over in #get-help.

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head to #get-help and #community:tips-and-resources. If you are wanting feedback or inspiration for a project, check out #project.

Looking for motivation to keep learning? Join our wider discussions in #community

Learn more about how to use this guide.

Found a bug? Report it online, or post in #community:Codecademy-Bug-Reporting

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

Once you has used the empty dependency array as the second argument in the useEffect(), the return statement is ever called when the Component unmounts?

I can’t see that behaviour if I refresh the window.

useEffect(() => {
    const intervalId = setInterval(() => {
      setTime((prev) => prev + 1);
    }, 1000);
    return () => {
      clearInterval(intervalId);
    }
}, []);

Yeah I may be wrong, but it seems like in this case, the empty dependency array is achieving the same effect as the ‘return’ statement. If I comment out the ‘return’ statement and keep the empty dependency array and refresh, the behavior remains the same.

I’m not sure if i’m the only one having this issue. But it doesn’t look like the return statement seems to clear the interval after step 2. The count still increases very quickly. Anyone else having this issue?

export default function Timer() {
  const [time, setTime] = useState(0);

  useEffect(()=>{
    const intervalId = setInterval(()=> {
      setTime((prev)=> prev+1)
    }, 1000)
  };
  return ()=> {clearInterval(intervalId)}
  )

You have placed the cleanup function outside the function called by useEffect. Have a look at the previous lesson “Clean Up Effects” to see where the cleanup function should be positioned.

The above snippet should be edited to:

useEffect(() => {
    const intervalId = setInterval(() => {
      setTime((prev) => prev + 1);
    }, 1000);
    return () => {
      clearInterval(intervalId);
    };
  });

Got it, that fixed it. Thanks Faraz! Been a little unclear on where to place brackets. But looks like useEffects first parameter looks for a function that contains the effect function, then after a semicolon (within the main function of the first parameter) if it finds another function it identifies it as the clean up function. That sound right?

As I understand it, the first argument to the useEffect is a callback function, while the second optional argument is an array of dependencies (we separate the two arguments by a comma).
So, the signature is useEffect(callback function, optional dependency array)
Within our callback function, we can implement whatever effects we want to happen. In the snippet you posted, we are doing just one effect involving the interval. If we wanted, we could do a series of effects. It is a good idea to separate the statements by semicolons. So, the basic structure would be something like:

useEffect(() => {
  effect 1;
  effect 2;
  effect 3;
}
)

While we can carry out multiple effects in a single callback function, the function can only have one return statement which should be placed at the bottom of the function. If we don’t want any cleanup function, then we can omit the return statement. If we do want a cleanup function, then the return statement should be placed at the bottom of the callback function. If we place the return statement earlier, then any effects after the return statement would be lost. We can only return one cleanup function, though within the cleanup function we can do multiple cleanups.
So, the structure is:

useEffect(() => {
  effect 1;
  effect 2;
  effect 3;
  return cleanup function;  // If we don't need to cleanup, 
                           //then we can omit return statement
}
)

useEffect understands that if the callback function is returning some function, then that returned function should be treated as a cleanup function.

1 Like