由于多种样式,React 组件重新渲染

tno*_*173 0 javascript performance reactjs react-native

当我传递多个样式时,我面临渲染问题,如下所示:

<StyledComponent style={[styles.styleOne, styles.styleTwo]} />

如果组件 StyledComponent 包含在重新渲染中,则 StyledComponent 也会重新渲染,即使道具没有改变。

我知道如果父组件调用 setState,那么它的子组件将重新渲染,而不管子组件自己的 props 是否实际发生变化。我尝试使用 PureComponent 和 React.memo。但是,我的子组件仍在重新渲染。似乎问题在于我发送样式的方式。如果我这样传递一种风格:

<StyledComponent style={styles.styleOne} />

PureComponent/React.memo 有效。但是,如果我的组件样式如下:

<StyledComponent style={[styles.styleOne, styles.styleTwo]} />

然后它每次都重新渲染。

这是因为我在每次渲染父组件时都会实例化一个新数组,而 PureComponent/React.memo 无法确定它们是相同的样式。

所以我的问题是,如何在一个组件上使用多种样式而不必在我的每个子组件上编写自定义 shouldComponentUpdate ?渲染显着降低了我的应用程序的性能,因为我使用的是较旧的 Android 设备,所以我想尽量减少所需的渲染。

这是证明这一点的小吃:https : //snack.expo.io/@tnortman/styles-r-stupid

Nic*_*wer 5

如果不想实现自定义的 shouldComponentUpdate,则需要确保数组通过===检查。这有几种可能性,具体取决于它如何或是否可以改变。如果它永远不会改变,那么这是最简单的:只需预先创建一次数组,然后引用它。例如:

const styles = StyleSheet.Create({
  styleOne: {
    backgroundColor: 'red',
  },
  styleTwo: {
    padding: 40,
  },
});

// Note that this line is not in render
const combined = [styles.styleOne, styles.styleTwo];

// ...

// in render:

<StyledPureComponent style={combined} />
Run Code Online (Sandbox Code Playgroud)

如果它有可能改变,那么你需要添加一些代码来管理它。最有可能的是,我会创建一个生成数组的记忆函数,并且只有在相关内容发生变化时才重新计算。例如,这是一个基于 prop 的示例,有时包含 style2,有时不包含:

// Just an example; you could use a different library or implement it yourself
import memoize from "memoize-one";

const combineStyles = memoize((shouldIncludeStyleTwo) => {
  const styles = [styles.styleOne];
  if (shouldIncludeStyleTwo) {
     styles.push(styles.styleTwo);
  }
  return styles;
});

// ...

<StyledPureComponent style={combineStyles(this.props.something)} />
Run Code Online (Sandbox Code Playgroud)