Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React Native StyleSheet提高代码质量和性能优化 #3

Open
1uokun opened this issue Apr 22, 2020 · 0 comments
Open

React Native StyleSheet提高代码质量和性能优化 #3

1uokun opened this issue Apr 22, 2020 · 0 comments
Labels
blog 日常开发笔记

Comments

@1uokun
Copy link
Member

1uokun commented Apr 22, 2020

目录

简介

StyleSheet 参考了CSS StyleSheets的类似的抽象写法

  • 创建一个新的StyleSheet:
    const styles = StyleSheet.create({
      container: {
        borderRadius: 4,
        borderWidth: 0.5,
        borderColor: '#d6d7da',
      },
      title: {
        fontSize: 19,
        fontWeight: 'bold',
      },
      activeTitle: {
        color: 'red',
      },
    });
  • 使用这个StyleSheet
    <View style={styles.container}>
       <Text style={[styles.title, this.props.isActive && styles.activeTitle]} />
    </View>
  • 使用StyleSheet可以提高代码质量:
    • 通过将样式从render()函数中分离,可以让代码更加容易理解
    • 通过命名样式对于语义化低级组件(RN自提供的组件)是一个很好的方案
  • 使用StyleSheet可以提高性能:
    • 使用StyleSheet.create()创建的样式可以通过ID重复引用,而内联样式则每次都需要创建一个新的对象
    • 它还允许仅通过桥(bridge)发送一次样式。 所有后续使用都将引用一个ID(尚未实现👈贡献RN的机会来啦

hairlineWidth

这个属性定义了各平台的细线的宽度。它可以被用在两个元素之间的边界(border)或分割的粗细值。
比如:

{
  borderBottomColor: '#bbb',
  borderBottomWidth: StyleSheet.hairlineWidth
}

该常数始终是像素的整数倍(因此,由其定义的线看起来会很清晰(look crisp?))并将尝试匹配基础平台上细线的标准宽度。但是您不应该依赖它作为一个恒定值使用,因为在不同平台和屏幕像素下,其值可能会以不同的方式计算。[1] 详见PixelRatio

如果缩小模拟器,用StyleSheet.hairlineWidth宽度定义的细线可能不可见

absoluteFill

一个非常常见的创建具有绝对位置零位置的叠加层样式,因此可以使用 absoluteFill来方便并减少那些不必要的重复样式。

//TODO: This should be updated after we fix downstream Flow sites.

absoluteFillObject

有时候您可能需要对absoluteFill的样式做一些调整,我们推荐您使用absoluteFillObjectStyleSheet中创建自定义条目。

const styles = StyleSheet.create({
  wrapper: {
    ...StyleSheet.absoluteFillObject,
    top: 10,
    backgroundColor: 'transparent',
  }
});

By the way,absoluteFill对象已经被冻结,所以无法修改absoluteFill

const absoluteFill = {
  position: 'absolute',
  left: 0,
  right: 0,
  top: 0,
  bottom: 0,
};
if (__DEV__) {
  Object.freeze(absoluteFill);
}

compose 已废弃

StyleSheet.compose(a, b) is deprecated; use array syntax, i.e., [a,b].

> compose(style1, style2)

组合两种样式,以便style2会覆盖style1中的同类型样式属性。

  • compose源码实现:
    function compose(style1, style2){
      if(style1 != null && style2 != null){
        return ([style1, style2])
      } else {
        return style1 != null ? style1 : style2;
      }
    }
  • 使用场景:
    当有一种样式需要受到状态(state)控制有无时,
    <View style={[style1, this.state.active&&style2]} />
    上述代码在DOM diff对比时样式属性则无法保持引用相等,所以需要使用StyleSheet.compose辅助函数方便实现:
    <View style={StyleSheet.compose(style1, this.state.active&&style2)} />

flatten

扁平化一个样式对象数组,返回一个聚合的样式对象。
或者,可以使用此方法查找由StyleSheet.register返回的IDs。

⚠️注意:请谨慎使用,因为这样可能会给您带来优化方面的负担。

通常,通过ID可以通过桥(bridge)和内存进行优化。直接引用样式对象将使您失去这些优化。

比如:

 const styles = StyleSheet.create({
   listItem: {
     flex: 1,
     fontSize: 16,
     color: 'white'
   },
   selectedListItem: {
     color: 'green'
   }
 });

 StyleSheet.flatten([styles.listItem, styles.selectedListItem])
 // returns { flex: 1, fontSize: 16, color: 'green' }

可以这样使用(二选一):

 StyleSheet.flatten(styles.listItem);
 // return { flex: 1, fontSize: 16, color: 'white' }
 // 仅仅styles.listItem 将返回它的 ID (number)

该方法在内部使用StyleSheetRegistry.getStyleByID(style)来解析由ID表示的样式对象。 因此,将样式对象的数组(StyleSheet.create的实例)分别解析为它们各自的对象,合并为一个对象然后返回。 这也解释了替代用法。

create

创建一个StyleSheet对象并引用给定的对象。

By the way,返回的对象也会被冻结不可被修改,所以建议在组件外部并使用const声明:

Class Demo extends Component {
  ...
}

const styles = StyleSheet.create({
  ...
})

Reference

@1uokun 1uokun added the blog 日常开发笔记 label Apr 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blog 日常开发笔记
Projects
None yet
Development

No branches or pull requests

1 participant