Oblicion A
Oblicion A

Reputation: 187

useEffect not triggering

I think my useEffect is broken.

I have on the parent component

 <div className={redactKategori}>
    <select className="form-control form-control-sm mb-3 mr-2" name="betalt" defaultValue={'välj kategori'} onChange={e => { e.preventDefault(); setKate(e.target.value); setRedactKategoris('d-block') }}>
      <option >valj kategori</option>
      { Kategori ?
        Object.keys(Kategori).map(key => {
          return (
            <option key={key} value={key}>{key}</option>
          )
        }) :
        null
      }
      </select>
    <div className={redactKategoris}>
  <EditKat aa={kate} />
</div>

and on the child component

function EditKat({ aa }) {
  let defaultValues = 0

  useEffect(() => {
    defaultValues = 2
  }, [aa])

  console.log(defaultValues)
}

So, as far as I understood, everytime ${kate} would get a value on the parent component, the child component would trigger the useEffect hook. However it is not working. Am I doing something wrong?

Upvotes: 8

Views: 51875

Answers (3)

Sairam Gourishetty
Sairam Gourishetty

Reputation: 700

I faced the same problem, I debugged it and i found that, i am mutating the state directly instead of cloning it and using it. So, that's why useEffect is not triggered.

Upvotes: 2

Abraham
Abraham

Reputation: 15830

Try adding a key prop on your component when it is created in the parent code

<yourcomponent key="uniquevalue" />

This is because in most cases, when your component is reused, based on the way it is created, it may usually re-render it with some changes instead of recreating it again when you reuse it, Hence the useEffect is not going to be called. eg in SwitchRoute, loops, conditionals...

So adding a key will prevent this from happening. If it is in a loop make sure each element is unique, maybe by including the index i in the key if you can't find any better unique key.

Upvotes: 1

Linschlager
Linschlager

Reputation: 1639

The reason for the experienced behavior is not that useEffect isn't working. It's because of the way function components work.

If you look at your child component, if useEffect is executed and the component rerenders, defaultValues would be set to 0 again, because the code inside of the function is executed on each render cycle.

To work around that, you would need to use the useState to keep your local state consistent across renders.

This would look something like this:

function EditKat({ aa }) {
  // Data stored in useState is kept across render cycles
  let [defaultValues, setDefaultValues] = useState(0)

  useEffect(() => {
    setDefaultValues(2) // setDefaultValues will trigger a re-render
  }, [aa])

  console.log(defaultValues)
}

Upvotes: 7

Related Questions