Let's say I have a performance-optimized component like this one:
const PerformanceComponent = ({style}) => {
return <View style={style}>...</View>
}
export default React.memo(PerformanceComponent)
and I am using the component inside the parent like this:
{someArray.map((style) => (
<PerformanceComponent style={style} />
)}
I am passing different objects for style
, it can look like this:
const styles = {
width: 200,
height: 200
}
Now React.memo will not do the trick because I am passing an object and React will only compare the memoryaddress (I think its called Shallow Compare).
What are my options to avoid unnecessary rerendering (PerformanceComponent
), even if the styles
-object did not change?
As other answers said, you need to pass a function as a second parameter to React.memo
that will receive the previous prop and the current prop so you can decide if the component should be rerendered or not (just like shouldComponentUpdate
lifecycle for class components).
Because comparing an entire object to see if anything changed can be a expensive operation (depending on the object) and because you can have multiple properties, one way to make sure it's efficient is to use lodash _.isEqual.
import { isEqual } from 'lodash'
const PerformanceComponent = ({style}) => {
return <View style={style}>...</View>
}
export default React.memo(PerformanceComponent, isEqual)
This way you don't have to worry about implementing the isEqual
and it also have a good performance.
You can add to the memo call a second argument which is a function receiving prevProps and nextProps so you can write some logic to compare them and return true if you want to avoid unnecessary rerendering.
More info here https://reactjs.org/docs/react-api.html#reactmemo
React.memo takes a second argument as comparison function. However, unlike shouldComponentUpdate it should return true to avoid re-rendering (although this is advised against as it can lead to bugs).
You can read more about it here https://reactjs.org/docs/react-api.html#reactmemo
In the comparison function you could either use lodash.isEqual if the object is large, or in your case something like this:
const isEqual = ({style: prevStyle}, {style: currStyle}) => {
return prevStyle.width === currStyle.width && prevStyle.height == currStyle.height
}
export default React.Memo(PerformanceComponent, isEqual)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With