Rachel V
Rachel V

Reputation: 137

react useEffect trigger although dependency value remain the same?

Why the log still trigger although I didn't do setTest to change the test value? I expect for the first time the log should not trigger because the test value remain 0?

function App() {
  const [test, setTest ] = useState(0)

  useEffect(() => {
    console.log('log')
  }, [test])

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

I have a scenario like this. on first load don't do anything, then if user select an option on the page then do something, how do I do that with useEffect?

Upvotes: 9

Views: 13977

Answers (2)

machineghost
machineghost

Reputation: 35790

From https: Using the Effect Hook

What does useEffect do? By using this Hook, you tell React that your component needs to do something after render. React will remember the function you passed (we’ll refer to it as our “effect”), and call it later after performing the DOM updates.

Your component rendered, useEffect triggered, and your log ran.

It sounds like you might be confusing useEffect (which only takes a single argument, a callback) with other hooks that take multiple arguments.

---- EDIT (Comments-Related) ----

useEffect is not a direct replacement for class-based componentDidMount and componentDidUpdate methods, but because of the timing of when it runs it can often be used to replace those methods. See for further info. You may also want to read about the related useLayoutEffect hook.

If your intent is to hook up some logic "on load", such as an event handler, you don't need a hook to do that. Instead you just need a React event handler attribute, eg.

<option onChange={changeHandler} />

(See for further info.)

Upvotes: 3

Hamid Pouladi
Hamid Pouladi

Reputation: 225

(1)first useEffect call is when component mount.

useEffect(() => {
    console.log('log')
  }, [test])

(2)if you pass second Array dependencies argument to useEffect and that argument wasn't empty, any time one of that dependency changes useEffect also recalled.

useEffect(() => {
    console.log('log')
  }, [test])

(3) if array of dependencies was empty, useEffect only one time called(after component mount for first time).

useEffect(() => {
    console.log('log')
  }, [])

(4)if useEffect implementing without second argument any time component state update useEffect also called.

useEffect(() => {
    console.log('log')
  })

for your situation you can check if test is 0 cancel execute useEffect body code like this:

function App() {
  const [test, setTest ] = useState(0)

  useEffect(() => {
   if(test < 1) return;
    console.log('log')
  }, [test])


  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

Upvotes: 5

Related Questions