在道具中传递物体时避免重新渲染孩子

时间:2020-08-20 09:54:57

标签: javascript reactjs react-hooks

假设我有一个性能优化的组件,例如:

{someArray.map((style) => (
    <PerformanceComponent style={style} />
)}

我正在像这样在父级内部使用组件:

style

我正在为const styles = { width: 200, height: 200 } 传递不同的对象,看起来像这样:

PerformanceComponent

现在React.memo不会解决这个问题,因为我传递了一个对象,而React只比较内存地址(我认为它叫做 Shallow Compare )。

即使styles对象没有变化,避免不必要的重新呈现SELECT itemID, orderID, sum(order_volume), sum(shipped_volume) FROM operations GROUP BY 1,2 HAVING sum(shipped_volume) > 0; )有哪些选择?

3 个答案:

答案 0 :(得分:2)

正如其他答案所述,您需要将一个函数作为第二个参数传递给React.memo,该函数将接收先前的属性和当前属性,以便您决定是否应重新呈现组件(就像{ {1}}类组件的生命周期。

由于要比较整个对象以查看是否有任何更改可能是一项昂贵的操作(取决于对象),并且由于您可以具有多个属性,因此确保其有效的一种方法是使用lodash _.isEqual。 / p>

shouldComponentUpdate

通过这种方式,您不必担心实现import { isEqual } from 'lodash' const PerformanceComponent = ({style}) => { return <View style={style}>...</View> } export default React.memo(PerformanceComponent, isEqual) 的情况,而且效果也不错。

答案 1 :(得分:1)

您可以在备忘录调用中添加第二个参数,该参数是一个接收prevProps和nextProps的函数,因此您可以编写一些逻辑比较它们,并在避免不必要的重新渲染时返回true。

此处更多信息https://reactjs.org/docs/react-api.html#reactmemo

答案 2 :(得分:1)

React.memo将第二个参数用作比较函数。但是,与shouldComponentUpdate不同,它应该返回true以避免重新渲染(尽管建议这样做,因为这可能会导致错误)。

您可以在这里https://reactjs.org/docs/react-api.html#reactmemo

了解更多信息

在比较函数中,如果对象很大,则可以使用lodash.isEqual,或者在您的情况下使用类似这样的东西:

const isEqual = ({style: prevStyle}, {style: currStyle}) => {
  return prevStyle.width === currStyle.width && prevStyle.height == currStyle.height
}

export default React.Memo(PerformanceComponent, isEqual)