现在前端圈子最热的莫过于ReactNative。以Web的开发方式来开发Native,并且仗这facebook这个国际互联网公司做保证,这种革命性的产品都让前端coder和客户端coder都炸开了。本文打算以ReactNative的Text标签的角度,这个最基本的标签,来带你跨入入ReactNative的世界的第一步。
如果把React Native 上的View标签对应成web的div标签,那么想把Text标签对应为web的Span标签或者P标签真是大错特错。严格来说,你应该把Text当初一个ReactNative的组件!(是的,本身就是!)Text标签在ReactNative上非常非常的常用,其属性方法,内部细节为开发者所必须掌握的。同时我们能透过Text标签,也能理解ReactNative上的一些设计理念。
这点大家应该都比较清楚,如果使用View标签输出文本,ReactNative是会直接报错的,我们必须用Text标签包起来。
// 直接编译不通过,少年Some text // successSome text
二,关于Text的嵌套
Text元素是一种特殊的相对布局。如果Text标签嵌套Text标签,Text内层的不再是flexbox布局,而是纯文本布局。即是,内层Text元素设置长宽间距都是没有效果的。另外,一点注意的是,Text元素内层也只能是Tex元素而已,其他元素会直接编译报错。但是如果Text元素的外层嵌套元素是View的话,这时候Text元素却又是块级元素,是能够使用flexbox布局。
看官方的一个Demo:
你的所言所行,全都闪烁着光芒,太过刺目,于是我闭上了眼睛,,, 但是内心还是无法停止对你的憧憬 你的所言所行,全都闪烁着光芒,太过刺目,于是我闭上了眼睛,,, 但是内心还是无法停止对你的憧憬
可以发现,Text内嵌Text可以理解为一个大Text元素,内部的Text元素都只是用于设置独立的文本样式。其设置了containerBackgroundColor由于只能作用于块级元素,而不生效。
使用View内嵌Text,内嵌的Text元素是个正常的块级元素(两个Text元素自动换行),并且可以设置长宽。containerBackgroundColor也正常。
再来举个看个例子
设置padding和flex 设置margin和flex
可以是看出,View元素的内嵌Text设置padding,margin甚至flex都是没有问题的。
三,Text的样式继承
废话不多说,我们直接看个例子。
你好,我的父层是View 你好,我的父层是Text
我们可以发现,父层是Text标签的时候,样式能够进行继承的。但当父层时View的时候,却不行。在Web上,如果我们在body标签上设置font-family,font-size,或者color等等,我们在任何一个没有覆盖这些样式的的Dom上面,是能够继承这些CSS属性的。但是在ReactNative 上是却没有这样的样式继承机制的!要想实现Web上常用的全局定义字体样式的方式,我们在最外层的View上面赋值是没有效果的。
或者换句话说:ReactNative中没有样式继承!只有嵌套的Text才能有font相关属性的继承能力。
四,设置全局文本样式
我们理解了Text的样式继承,及其元素嵌套对Text元素的影响。但是很快就发现了我们实际项目开发中非常常见的问题:如何设置全局文本样式?
我就不卖关子,解决方案是:Component + Text标签内联
根据React的Component设计,让每一公共的文本样式定义一个Component!是的,你没有听错,为一个公共的文本样式或者一个Class定义一个Component。React框架的设计是希望一个App就是一个大的Component,各个功能模块又是由Component组成,而每个功能模块Component又能划分各个小的Component的,而在ReactNative的世界里,你可能需要为一段文本样式定义一个这样的Component。可见其Component划分的粒度之细。
五,为什么这样设计? For Component
我们先来另外一个问题: 为什么要设置Text标签(组件)
当浏览器尝试渲染一个text node节点,会遍历dom树的上层直到遇到有font-size的属性,然后渲染。而这个过程中,任何的dom节点都是可以有font-size属性,而Web的这种设计是方便易用性,img标签也是可以的,即使语义是不正确的。
而在ReactNative中,将严格控制这点。你必须包裹文本使用Text标签,不能使用View及其它标签组件。也是正是这一规定,我们不能在全局设置文本样式。但是我们推荐你封装一个Component来定义你的全局样式!是的,你可以设置一个MyAppText来设置全局文本样式,同时再设置一个MyTitleText,MyDescText等来设置不同组件,实现不同的样式继承问题。在ReactNative上,全民组件,即使是一个Class也可以封装成一个Component,这也是react的设计思想。
这种严谨的约束的文本风格,将会产生更好的应用。
一方面,React组件设计时考虑到更加严谨的独立隔离环境,这一你的这个组件就能够在任何应用程序上应用而不带有任何依赖,包括样式。只要相信组件传递的属性是相同的,组件渲染和行为都是一样的。如果我们的文本风格按照Web上的继承关系,组件间的样式将会相互影响,而违背组件的独立性。而这样严谨的独立性,对于组件的复用和可移植性来讲是必不可少的
另一方面,这一的设计对代码实现是简单的。我们不需要遍历整个Dom树来决定要显示的每一个文本节点。文本样式继承只是在组件内部,不影响其他组件和系统本身。这样在ReactNative的实现机制上,简单而又高效,一举两得。