Reputation: 365
I am mapping through an array, which returns JSX Components for each of the items in the array. During runtime I want to pass down values. If they match the value of the individual items, their individual component gets modified.
I am trying to find a way to achieve this without rerendering all components, which currently happens because the props change
I have tried using shouldComponentUpdate in a class component, but it seems this way I can only compare prevState and prevProps with the corresponding changes. I have further considered useMemo in the Map function, which didnt work, because it was nested inside the map function.
const toParent=[1,2,4,5]
Parent Component:
function parent({ toParent }) {
const [myNumbers] = useState([1,2,3,4, ..., 1000]);
return (
<div>
{myNumbers.map((number, index) => (
<Child toChild = { toParent } number = { number }
index= { index } key = { number }/>
))}
</div>
)
}
Child Component:
function Child({toChild, number, index}){
const [result, setResult] = useState(() => { return number*index }
useEffect(()=> {
if (toChild.includes(number)) {
let offset = 10
setResult((prev)=> { return { prev+offset }})
}
}, [toChild])
return (
<div style={{width: result}}> Generic Div </div> )
}
Upvotes: 3
Views: 1604
Reputation: 365
The solution to my problem was using the React.memo HOC and comparing the properties to one another and exporting it as React.memo(Child, propsAreEqual)
.
This way other methods like findElementbyId (not recommended in any case) and shouldComponentUpdate to target specific items in a map function can be avoided. Performance is quite good, too. Using this method cut down the rendering time from 40ms every 250ms to about 2 ms.
In Child Component:
function Child(){...}
function propsAreEqual(prev, next) {
//returning false will update component, note here that nextKey.number never changes.
//It is only constantly passed by props
return !next.toChild.includes(next.number)
}
export default React.memo(Child, propsAreEqual);
or alternatively, if other statements should be checked as well:
function Child(){...}
function propsAreEqual(prev, next) {
if (next.toChild.includes(next.number)) { return false }
else if ( next.anotherProperty === next.someStaticProperty ) { return false }
else { return true }
}
export default React.memo(Key, propsAreEqual);
Upvotes: 4