Home > Mobile >  UseEffect not working provided I am passing an object to it
UseEffect not working provided I am passing an object to it

Time:07-12

even though the ThemeChange object changes everytime the App component gets rerendered... I still don't know why it is not causing useEffect to execute whenever I either change the number or click on toggleTheme button... I am severely confused

import React,{useState, useMemo, useEffect} from 'react'
import './App.css';

function App() {
  const [dark, setDark] = useState(false),
  [number, setNumber] = useState(0)
  
  const SlowFunction = num => {
    for(let i=1; i<=10000;   i) {}
    return num*2
  }
  
  const TwiceNo = useMemo(() => {
    return SlowFunction(number)
  }, [number])

   const ThemeChange = {
      backgroundColor : dark ? 'black' : 'white',
      color : dark ? 'white' : 'black' 
  }
 
  useEffect(() => {
    console.log('theme was changed!')
  }, [ThemeChange])
  

  
  return (
    <div className="App">
      <input type="number" onChange = {e => {setNumber(parseInt(e.target.value), console.log(e))}} />
      <button onClick={() => setDark(e => !e)}>toggle theme</button>
      <div style={ThemeChange}>{TwiceNo}</div>
    </div>

);
}

export default App;

CodePudding user response:

Javascript objects will not be the same when your component is rerender ( google search more about that) -> Your effect will run every time component rerender because the deps is different. Try to specify the deps.

Like this

useEffect(() => { console.log(Date.now(), "theme was changed!"); }, [ThemeChange.backgroundColor, ThemeChange.color]);

or even better version use this useEffect(() => { console.log(Date.now(), "theme was changed!"); }, [dark]);

CodePudding user response:

Objects are tracked by reference, so there is 2 ways to achieve your goal:

  • Set a object with a new reference like using spread operator, or Object.assign
  • Check for object equality using JSON.stringify (not recommended for deep objects though)

So try

  useEffect(() => {
    console.log('theme was changed!')
  }, [JSON.stringify(ThemeChange)])
  • Related