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

Javascript 由于多种样式,React组件重新渲染,javascript,reactjs,performance,react-native,Javascript,Reactjs,Performance,React Native,当我传递多个样式时,我面临渲染问题,如下所示: 如果组件StyledComponent包含在重新渲染中,StyledComponent也将重新渲染,即使道具不变 我知道,若父组件调用setState,那个么它的子组件将重新渲染,而不管子组件自己的道具是否实际更改。我试着利用PureComponent和React.memo。但是,我的子组件仍在重新渲染问题似乎在于我发送样式的方式。如果我这样发送一种样式: PureComponent/React.memo可以工作。但是,如果我的组件的样式是这样

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

如果组件StyledComponent包含在重新渲染中,StyledComponent也将重新渲染,即使道具不变

我知道,若父组件调用setState,那个么它的子组件将重新渲染,而不管子组件自己的道具是否实际更改。我试着利用PureComponent和React.memo。但是,我的子组件仍在重新渲染问题似乎在于我发送样式的方式。如果我这样发送一种样式:

PureComponent/React.memo可以工作。但是,如果我的组件的样式是这样的:

然后每次都会重新渲染

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

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

以下是一种小吃,可以证明这一点:

如果不想实现自定义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} />
constyles=样式表。创建({
样式一:{
背景颜色:“红色”,
},
样式二:{
填充:40,
},
});
//请注意,该行不在渲染中
const combled=[styles.styleOne,styles.styleTwo];
// ...
//在渲染中:
如果它有可能改变,那么您需要添加一些代码来管理它。最有可能的是,我会创建一个生成数组的记忆函数,并且仅在相关内容发生更改时才重新计算。例如,以下是一个基于道具的示例,它有时包含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)} />
//只是一个例子;您可以使用不同的库,也可以自己实现它
从“备忘录化一”导入备忘录化;
const combineStyles=memoize((应该包括styletwo)=>{
constyles=[styles.styleOne];
如果(应包括样式二){
styles.push(styles.styleTwo);
}
返回样式;
});
// ...

如果不想实现自定义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} />
constyles=样式表。创建({
样式一:{
背景颜色:“红色”,
},
样式二:{
填充:40,
},
});
//请注意,该行不在渲染中
const combled=[styles.styleOne,styles.styleTwo];
// ...
//在渲染中:
如果它有可能改变,那么您需要添加一些代码来管理它。最有可能的是,我会创建一个生成数组的记忆函数,并且仅在相关内容发生更改时才重新计算。例如,以下是一个基于道具的示例,它有时包含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)} />
//只是一个例子;您可以使用不同的库,也可以自己实现它
从“备忘录化一”导入备忘录化;
const combineStyles=memoize((应该包括styletwo)=>{
constyles=[styles.styleOne];
如果(应包括样式二){
styles.push(styles.styleTwo);
}
返回样式;
});
// ...

将样式数组移出类的实例变量,并通过props传递引用。这样,每次渲染都不是一个新数组。

将styles数组移出到类的实例变量中,并通过props传递引用。这样,每次渲染都不是一个新的数组。

为什么不在渲染函数之外将样式数组声明为一个常量。假设它们不会改变。我可以这样做,并且发现它已经工作了,但我认为主要的问题是PureComponent没有捕捉到这种情况。React原生文档甚至建议使用[styles.styles,styles.styles2]语法:PureComponent只对道具做了一个粗略的比较。它不打算捕捉这种情况。感谢您澄清为什么不在渲染函数之外将样式数组声明为常量。假设它们不会改变。我可以这样做,并且发现它已经工作了,但我认为主要的问题是PureComponent无法捕捉这种情况。React原生文档甚至建议使用[styles.styles,styles.styles2]语法:PureComponent只对道具做了一个粗略的比较。这不是为了抓住这个案子,谢谢你的澄清