admin管理员组

文章数量:1405140

Let's say I have a performance-optimized ponent like this one:

const PerformanceComponent = ({style}) => {
     return <View style={style}>...</View>
}

export default React.memo(PerformanceComponent)

and I am using the ponent 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 pare 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?

Let's say I have a performance-optimized ponent like this one:

const PerformanceComponent = ({style}) => {
     return <View style={style}>...</View>
}

export default React.memo(PerformanceComponent)

and I am using the ponent 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 pare 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?

Share Improve this question edited Aug 20, 2020 at 19:20 mleister asked Aug 20, 2020 at 9:54 mleistermleister 2,6343 gold badges31 silver badges50 bronze badges 1
  • you can use shouldComponentUpdate. – Sain Pradeep Commented Aug 20, 2020 at 10:14
Add a ment  | 

3 Answers 3

Reset to default 3

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 ponent should be rerendered or not (just like shouldComponentUpdate lifecycle for class ponents).

Because paring 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.

React.memo takes a second argument as parison 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/docs/react-api.html#reactmemo

In the parison 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)

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 pare them and return true if you want to avoid unnecessary rerendering.

More info here https://reactjs/docs/react-api.html#reactmemo

本文标签: javascriptAvoid rerendering child when passing object in propsStack Overflow