4

I am new to React and have a hard time understanding why when I call useEffect after I just set the new state on a variable, the new value is undefined. Can someone also explain why the second UseEffect hook is called twice. Is it because it's called on initial mount, and then called when it finally changes state from the first useEffect? How can I get it to fire only once val has a defined value that was set in the first useEffect?

import React from 'react';
import {useState, useEffect} from 'react'

export function App(props) {
  const [val, setVal] = useState();
  useEffect(() => {
    setVal("hello");
  },[]);
  useEffect(() => {
    console.log("value: ", val);
  }, [val])

  return (
    <div className='App'>
    </div>
  );
}
3
  • Calling useEffect doesn't set the value--calling useEffect registers a funtion that does something at an arbitrary time in the future based on its dependencies. Commented May 10, 2023 at 20:30
  • I understand that, but Im using setState in the useEffect though which sets the value, on intiail load right? Commented May 10, 2023 at 20:34
  • 2
    @anon: "which sets the value, on intiail load right?" - No. It queues a state update to occur after the component finishes rendering. That state update then triggers a re-render. If you want the state to have a value when the component first loads, initialize the state to that value: const [val, setVal] = useState("hello"); Commented May 10, 2023 at 20:36

1 Answer 1

2

The code is working exactly as I'd expect it to.

On (or more specifically, immediately after) the first render, both effects execute. Which:

  • queues a state update and
  • logs undefined to the console

Then when state is updated, the component re-renders. This re-render has a new state value for val, which triggers the second useEffect to execute. Which:

  • logs "hello" to the console

How can I get it to fire only once val has a defined value that was set in the first useEffect?

If you want something to happen conditionally, you'd use an if statement. For example:

useEffect(() => {
  if (val) {
    console.log("value: ", val);
  }
}, [val])

This will only log val to the console if it has a "truthy" value.

Sign up to request clarification or add additional context in comments.

3 Comments

This makes a lot of sense. One question though, how is it that in this case, refreshToken is set on the first UseEffect, and used on the second UseEffect without checking for a valid value without a problem? github.com/WebDevSimplified/spotify-clone/blob/main/client/src/…
@anon: "without checking for a valid value" - Look at the first line of the second useEffect again. The code is using an if statement to conditionally perform an action.
Oops thought the whole body was executing only if that if condition was true, didnt see the return at the end of line. Got it, thanks!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.