RN基础
原生组件
使用对应的React component, 可以轻松的将原生组件整合到RN应用中, 例如TabBarIOS和DrawerLayoutAndroid
异步执行
在Javascript代码和原生平台之间的所有操作都是异步执行的, 并且原生模块还可以根据需要创建新的线程
Props(属性)
React Native看起来很像React, 只不过基础组件为原生组件, 大多数组件创建时就可以使用各种参数来定制, 用于定制的这些参数就叫做属性->Props
export default class App extends Component<Props> {
render() {
let pic = {
uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
};
return (
<Image source={pic} style={{width: 193, height: 110}} /> //source指定地址, style指定尺寸
);
}
}
复制代码
{pic}外围括号的内部为一个js变量或者表达式, 需要执行后取值, 因此我们可以把任意合法的JavaScript表达式通过括号嵌入到JSX语句中, 自定义的组件也可以使用, 只需要在render函数中引用this.props
import React, { Component } from 'react';
import { Text, View } from 'react-native';
class Greeting extends Component {
render() {
return (
<Text>Hello {this.props.name}!</Text>
);
}
}
export default class LotsOfGreetings extends Component {
render() {
return (
<View style={{alignItems: 'center'}}>
<Greeting name='Rexxar' />
<Greeting name='Jaina' />
<Greeting name='Valeera' />
</View>
);
}
}
复制代码
State(状态)
通过props和state两种数据来控制一个组件, props是在父组件中指定, 而且一经指定, 被指定的组件的生命周期中则不再改变; 对于需要改变的数据我们需要来使用state
一般来说,你需要在constructor中初始化state(译注:这是ES6的写法,早期的很多ES5的例子使用的是getInitialState方法来初始化state,这一做法会逐渐被淘汰),然后在需要修改时调用setState方法
例如制作一段不停闪烁的文字, 文字内容本身已经指定好, 文字内容本身应该是一个prop, 文字显示则是随着时间变化, 这一状态应该写到state中
class Blink extends Component {
constructor(props) {
super(props);
this.state = { showText: true };
// 每1000毫秒对showText状态做一次取反操作
setInterval(() => {
this.setState(previousState => {
return { showText: !previousState.showText };
});
}, 1000);
}
render() {
// 根据当前showText的值决定是否显示text内容
let display = this.state.showText ? this.props.text : ' ';
return (
<Text>{display}</Text>
);
}
}
export default class BlinkApp extends Component {
render() {
return (
<View>
<Blink text='I love to blink' />
<Blink text='Yes blinking is so great' />
<Blink text='Why did they ever take this out of HTML' />
<Blink text='Look at me look at me look at me' />
</View>
);
}
}
复制代码
一般情况, 不会在定时函数 setInterval 或者 setTimeout 等中来操作state, 典型的场景是在接受到服务器返回的新数据, 或者在用户输入数据之后, State的工作原理和React.js完全一致
样式
所有的核心组件都接受名为style的属性, 使用JavaScript来写样式, 这些样式名称基本遵循了web上的CSS的命名, 只是按照JS的语法要求使用驼峰命名
style属性是一个普通的JavaScript对象, 可以传入一个数组, 在数组位置居后样式对象比居前的优先级更高, 这样可以间接实现样式的继承
建议使用StyleSheet.create来集中定义组件的样式
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View } from 'react-native';
export default class LotsOfStyles extends Component {
render() {
return (
<View>
<Text style={styles.red}>just red</Text>
<Text style={styles.bigblue}>just bigblue</Text>
<Text style={[styles.bigblue, styles.red]}>bigblue, then red</Text>
<Text style={[styles.red, styles.bigblue]}>red, then bigblue</Text>
</View>
);
}
}
const styles = StyleSheet.create({
bigblue: {
color: 'blue',
fontWeight: 'bold',
fontSize: 30,
},
red: {
color: 'red',
},
});
AppRegistry.registerComponent('LotsOfStyles', () => LotsOfStyles);
复制代码
一般按照顺序声明和使用style属性, 以借鉴CSS中"层叠"做法, 以后声明的属性会先覆盖声明的同名属性
高度与宽度
React Native中的尺寸都是无单位的, 表示的为: 与设备像素外观的逻辑像素点
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
export default class FixedDimensionsBasics extends Component {
render() {
return (
<View>
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
<View style={{width: 100, height: 100, backgroundColor: 'skyblue'}} />
<View style={{width: 150, height: 150, backgroundColor: 'steelblue'}} />
</View>
);
}
};
// 注册应用(registerComponent)后才能正确渲染
// 注意:只把应用作为一个整体注册一次,而不是每个组件/模块都注册
AppRegistry.registerComponent('AwesomeProject', () => FixedDimensionsBasics);
复制代码
弹性( Flex )宽高
在组件样式中使用flex可以动态的扩张或收缩, 一般而言使用flex:1来指定某个组件以撑满所有剩余空间, 如果多个并列的子组件使用flex:1来制定, 那么这些子组件会平分父容器剩余的空间, 如果这些并列的子组件的flex值不一样, 则谁的值越大, 谁占用的空间就越大,也就是说剩余的空间比等于并列组件间flex值得比
组件能够撑满剩余空间的前提是其父容器的尺寸不为零。如果父容器既没有固定的width和height,也没有设定flex,则父容器的尺寸为零。其子组件如果使用了flex,也是无法显示的
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
export default class FlexDimensionsBasics extends Component {
render() {
return (
// 试试去掉父View中的`flex: 1`。
// 则父View不再具有尺寸,因此子组件也无法再撑开。
// 然后再用`height: 300`来代替父View的`flex: 1`试试看?
<View style={{flex: 1}}>
<View style={{flex: 1, backgroundColor: 'powderblue'}} />
<View style={{flex: 2, backgroundColor: 'skyblue'}} />
<View style={{flex: 3, backgroundColor: 'steelblue'}} />
</View>
);
}
};
AppRegistry.registerComponent('AwesomeProject', () => FlexDimensionsBasics);
复制代码
使用Flexbox布局
在RN中使用flexbox规则来制定某个组件的子元素的布局, flexbox可以在不同的屏幕尺寸上提供一直的布局结构, 一般来说,使用flexDirection、alignItems和 justifyContent三个样式属性就已经能满足大多数布局需求
Flex Direction
在组件的style中指定flexDirection可以决定布局的主轴, 水平轴(row), 竖直轴(column), 默认为竖直轴
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
class FlexDirectionBasics extends Component {
render() {
return (
// 尝试把`flexDirection`改为`column`看看
<View style={{flex: 1, flexDirection: 'row'}}>
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
<View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
<View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
</View>
);
}
};
AppRegistry.registerComponent('AwesomeProject', () => FlexDirectionBasics);
复制代码
Justify Content
在组件的style中指定justifyContent可以决定其子元素沿着主轴的排列方式; 子元素是应该靠近主轴的起始端还是末尾段分布呢?亦或应该均匀分布?对应的这些可选项有:flex-start、center、flex-end、space-around以及space-between
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
class JustifyContentBasics extends Component {
render() {
return (
// 尝试把`justifyContent`改为`center`看看
// 尝试把`flexDirection`改为`row`看看
<View style={{
flex: 1,
flexDirection: 'column',
justifyContent: 'space-between',
}}>
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
<View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
<View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
</View>
);
}
};
AppRegistry.registerComponent('AwesomeProject', () => JustifyContentBasics);
复制代码
Align Items
在组件的style中指定alignItems可以决定子元素的次轴, start center flex-end stretch
注意:要使stretch选项生效的话,子元素在次轴方向上不能有固定的尺寸。以下面的代码为例:只有将子元素样式中的width: 50去掉之后,alignItems: 'stretch'才能生效
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
class AlignItemsBasics extends Component {
render() {
return (
// 尝试把`alignItems`改为`flex-start`看看
// 尝试把`justifyContent`改为`flex-end`看看
// 尝试把`flexDirection`改为`row`看看
<View style={{
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
}}>
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
<View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
<View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
</View>
);
}
};
AppRegistry.registerComponent('AwesomeProject', () => AlignItemsBasics);
复制代码