react-native 学习
cd AwesomeProject
react-native run-ios
ps:可以使用--version
参数(注意是两
个杠)创建指定版本的项目。例如react-native init MyApp --version 0.44.3。
0.45及以上版本需要下载boost库编译 —》查看
http://bbs.reactnative.cn/topic/4301/ios-rn-0-45%E4%BB%A5%E4%B8%8A%E7%89%88%E6%9C%AC%E6%89%80%E9%9C%80%E7%9A%84%E7%AC%AC%E4%B8%89%E6%96%B9%E7%BC%96%E8%AF%91%E5%BA%93-boost%E7%AD%89
在模拟器中,commond+R是重新加载
属性(props)的使用
//自定义的控件
class Greeting extends Component {
render() {
return (
Hello {this.props.name}!
);
}
}
//调用自定义控件
class LotsOfGreetings extends Component {
render() {
return (
);
}
}
props
是在父组件中指定,而且一经指定,在被指定的组件的生命周期中则不再改变
对于需要改变的数据,我们需要使用state
一般在 constructor中初始化 state,在需要修改时调用setState
方法
组件的生命周期。
组件的生命周期分成三个状态:
Mounting:已插入真实 DOM
Updating:正在被重新渲染
Unmounting:已移出真实 DOM
React 为每个状态都提供了两种处理函数,will函数在进入状态之前调用,did函数在进入状态之后调用,三种状态共计五种处理函数。
componentWillMount():只会在装载之前调用一次,在 render之前调用,你可以在这个方法里面调用setState改变状态,并且不会导致额外调用一次 render
componentDidMount():只会在装载完成之后调用一次,在 render之后调用,从这里开始可以通过ReactDOM.findDOMNode(this)获取到组件的 DOM 节点。
componentWillUpdate(object nextProps, object nextState)
componentDidUpdate(object prevProps, object prevState)
componentWillUnmount():卸载组件触发
此外,React还提供两种特殊状态的处理函数。
componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用
shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用
特别注意:以下这些方法不会在首次 render组件的周期调用
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
componentDidUpdate
创建组件实例并插入DOM时,会调用:
constructor()
//初始化 state 的位置,如果不需要初始化 state 并且不绑定方法的话,则不用实现该构造函数,注意state
不会随着任何props更新而更新,所以不要这样写:componentWillMount()
render() //
在调用时,应该检查this.props
和this.state
,并返回一个作出反应的元素。此元素可以是本机DOM组件的表示形式,也可以是
您自己定义的另一个复合组件。您也可以返回null
或false
指示您不想要任何呈现。当返回null
或者false
,ReactDOM.findDOMNode(this)
将返回null
如果
shouldComponentUpdate()
返回false,则render()不会被调用
componentDidMount()
componentWillReceiveProps()
this.setState
一般不会触发该方法
shouldComponentUpdate()
componentWillUpdate()
,render()
和componentDidUpdate()
将不会被调用,所以可以通过比较this.props
与nextProps
和this.state与
nextState来告诉组件跳过更新。
componentWillUpdate()
shouldComponentUpdate()返回 false 的时候,这个方法不会被调用。
render()
componentDidUpdate()
componentWillUnmount()
每个组件还提供了一些其他API:
setState()
prevState
是对以前状态的引用。不应该直接改变它,而是应该根据prevState
和props构建一个新对象来表示更改。例如,
假设我们想增加一个状态值props.state
:
this.setState((prevState, props) => {
return {counter: prevState.counter + props.step};
});
第二个参数是一个可选的回调函数,官方建议用componentDidUpdate代替它的使用。
如果下一个 state 仅依赖上一个 state,官方建议如下形式使用:
this.setState((prevState) => {
return {counter: prevState.quantity + 1};});
forceUpdate()
defaultProps
如果props.color
没有提供,它将默认设置为'blue'
:
render() {
return ; // props.color will be set to blue
}
如果props.color
设置为null,它将保持为空:
render() {
return ; // props.color will remain null
}
displayName
props
state
在组件样式中使用flex
可以使其在可利用的空间中动态地扩张或收缩。一般而言我们会使用flex:1
来指定某个组件扩张以撑满所有剩余的空间。如果有多个并列的子组件使用了flex:1
,则这些子组件会平分父容器中剩余的空间。如果这些并列的子组件的flex
值不一样,则谁的值更大,谁占据剩余空间的比例就更大(即占据剩余空间的比等于并列组件间flex
值的比)。
ps: flexDirection标签控制 flex 拉伸方向(控制主轴方向),默认是column竖直轴(默认拉伸高度),可以设置成水平轴(row
)
justifyContent标签可以控制子组件的排列顺序,分别是:
flex-start:
主轴首部
center:主轴中部
flex-end:主轴尾部
space-around:组件在主轴方向按固定间距排列(比如每个组件都是左右间距50或者每个组件上下间距都是50)
space-between:主轴方向等间距排列。
在组件的style中指定alignItems
可以决定其子元素沿着次轴
对应的这些可选项有:flex-start
、center
、flex-end
以及stretch
。
注意:要使stretch
选项生效的话,子元素在次轴方向上不能有固定的尺寸
style 賦值
e.g.:
class LotsOfStyles extends Component {
render() {
return (
just red
just bigblue
bigblue, then red
red, then bigblue
);
}
}
const styles = StyleSheet.create({
bigblue: {
color: 'blue',
fontWeight: 'bold',
fontSize: 30,
},
red: {
color: 'red',
},
});
后声明的属性会覆盖先声明的同名属性(上面的例子是覆蓋了 color 這個屬性)
Textinput
从TextInput里取值这就是目前唯一的做法:订阅它的onChangeText
事件来读取用户的输入,即使用onChangeText
写入state,然后从this.state中取出值
TextInput
在安卓上默认有一个底边框,同时会有一些padding。如果要想使其看起来和iOS上尽量一致,则需要设置padding: 0
,同时设置underlineColorAndroid="transparent"
来去掉底边框。
又,在安卓上如果设置multiline = {true}
,文本默认会垂直居中,可设置textAlignVertical: 'top'
样式来使其居顶显示。
又又,在安卓上长按选择文本会导致windowSoftInputMode
设置变为adjustResize
,这样可能导致绝对定位的元素被键盘给顶起来。要解决这一问题你需要在AndroidManifest.xml中明确指定合适的windowSoftInputMode
( https://developer.android.com/guide/topics/manifest/activity-element.html )值,或是自己监听事件来处理布局变化
长列表(listview):FlatList或是SectionList。
FlatList:没有组视图
const myListData = [ {key: 'Devin'}, {key: 'Jackson'}, {key: 'James'}, {key: 'Joel'}, {key: 'John'}, {key: 'Jillian'}, {key: 'Jimmy'}, {key: 'Julie'}, ]; export default class MyListViewDemo extends Component<{}> { render() { return (
导航栏:目前主推react-navigation
只针对iOS平台开发,并且想和系统原生外观一致,那么可以选择NavigatorIOS
e.g.:
//只有声明了
{ navigation }的才能继续跳转。
const HomeScreen = ({ navigation }) => (
navigation.navigate('Details’) //跳转到” Details"界面}
title="Go to details" /> ); const DetailsScreen = () => (
StackNavigator,注册导航栏所在的窗口视图
const RootNavigator = StackNavigator({ Home: { screen: HomeScreen, navigationOptions: {
//导航栏标题 headerTitle: 'Home', }, }, Details: { screen: DetailsScreen, navigationOptions: {
//导航栏标题 headerTitle: 'Details', }, }, }); export default class MainScreen extends Component<{}> { render() { return (
其他:TabNavigator、DrawerNavigator参考:https://reactnavigation.org/docs/intro/quick-start
属性(个别需要特别注意的)
决定弹出的何种软键盘的,譬如numeric
(纯数字键盘)。
这些值在所有平台都可用:
决定“确定”按钮显示的内容。在Android上你还可以使用returnKeyLabel
来自定义文本。
跨平台
下列这些选项是跨平台可用的:
done
go
next
search
send
限Android
下列这些选项仅限Android使用:
none
previous
限iOS
下列这些选项仅限iOS使用:
default
emergency-call
google
join
route
yahoo
加载图片
http://reactnative.cn/docs/0.49/images.html
ps: 在iOS上,每次调整Image组件的宽度或者高度,都需要重新裁剪和缩放原始图片。这个操作开销会非常大,尤其是大的图片。比起直接修改尺寸,更好的方案是使用transform: [{scale}]
的样式属性来改变尺寸。比如当你点击一个图片,要将它放大到全屏的时候,就可以使用这个属性
resizeMode的属性:cover(默认),contain(全部展示图片,自动缩放)、stretch(拉伸图片,让宽或者高占满控件)
设置背景色为透明色: backgroundColor: ‘transparent’
各种颜色参数:http://reactnative.cn/docs/0.49/colors.html#content
可点击/长按的组件(点击效果按钮)
一般来说,你可以使用TouchableHighlight来制作按钮或者链接。注意此组件的背景会在用户手指按下时变暗。
在Android上还可以使用TouchableNativeFeedback,它会在用户手指按下时形成类似墨水涟漪的视觉效果。
TouchableOpacity会在用户手指按下时降低按钮的透明度,而不会改变背景的颜色。
如果你想在处理点击事件的同时不显示任何视觉反馈,则需要使用TouchableWithoutFeedback。
e.g.:
onLongPress = {() => Alert.alert("这是长按效果")}>
定时器使用
需要注意的是铭记在unmount组件时清除(clearTimeout/clearInterval)所有用到的定时器
直接操作组件setNativeProps的简单使用:http://reactnative.cn/docs/0.49/direct-manipulation.html#content
升级教程:http://reactnative.cn/docs/0.49/upgrading.html#content
特定平台代码的区分:http://reactnative.cn/docs/0.49/platform-specific-code.html#content
React Native会检测某个文件是否具有.ios.
或是.android.
的扩展名,然后根据当前运行的平台加载正确对应的文件。
假设你的项目中有如下两个文件:
BigButton.ios.js
BigButton.android.js
这样命名组件后你就可以在其他组件中直接引用,而无需关心当前运行的平台是哪个。
import BigButton from './components/BigButton';
React Native会根据运行平台的不同引入正确对应的组件。
实用的方法是Platform.select()
e.g.:
import { Platform, StyleSheet } from 'react-native';
var styles = StyleSheet.create({
container: {
flex: 1,
...Platform.select({
ios: {
backgroundColor: 'red',
},
android: {
backgroundColor: 'blue',
},
}),
},
});
上面的代码会根据平台的不同返回不同的container样式——iOS上背景色为红色,而android为蓝色。
这一方法可以接受任何合法类型的参数,因此你也可以直接用它针对不同平台返回不同的组件,像下面这样:
var Component = Platform.select({
ios: () => require('ComponentIOS'),
android: () => require('ComponentAndroid'),
})();
;