Reputation: 187
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
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
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
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