I’ve a parent component and a child component. I’m using array.map() method to call the child component for every value in the messages array.
now I want to do something inside the child component every time a button in the parent is clicked. so I’ve set up a useEffect with a dep array, inside the child.
Is this the right approach?
because if there are a 100 values inside the array the useEffect will be called those many times.
and if I’m doing something heavy such as using a for loop inside the effect, won’t it be a bad implementation.
is there a better approach for this scenario? especially when I only want to run the useffect for a few selected array values.
parent component:
import React, {useState} from 'react';
export function App() {
let [clicked,setClicked] = useState(false);
let messages = ['a','n','c','d'];
let changer = () =>{
setClicked(true);
}
return (
<div className='App'>
{messages.map((o) => (
<div>
<Childcomp clicked={clicked}/>
</div>
))}
<button onClick={changer}> click me </button>
</div>
);
}
child component:
import React, {useState, useEffect} from 'react';
export function Child({clicked}) {
useEffect(()=>{
if(clicked){
console.log('parent tapped :)'); // do something useful/heavy
}
},[clicked])
return (
<div className='child'>
<p className='class1'>hi i'm child</p>
</div>
);
}
2
Answers
Try this, if component will render for first item of array then
useEffect
will called. for the other items of arrayuseEffect
will return and will not do anything.You are right, with your implementation when
clicked
state change value in the parent component,useEffect
of each returnedChildcomp
will fire sinceclicked
props is included in the dependecy arrayIt seems like you want to run
useEffect
only for one specificChildcomp
but which one? it is not clear with your implementation, since hereclicked
state is a simple boolean value.If I understood correctly what you want to achieve, you might need to store the index of the clicked
Childcomp
inclicked
state because otherwise, you’ll have no information about which child component should run itsuseEffect
hook:Now with this update, each time you click the wrapper
div
of oneChildcomp
you store itsindex
inclicked
state.Note: if it is possible, better to store
o.id
and use it asindex
.I kow thet
o
is a string here but maybe this is a simple example.In the child component, you still need to fire
useEffect
each timeclicked
props changes, you can’t avoid that, but you can make the code inside the effect run only when the clicked child component is that one, i.e. whenindex
props is equal toclicked
propscodesandbox