由来:
Facebook 在2015年初React.js技术研讨大会上公布的一个开源项目。支持用开源的JavaScript库React.js来开发iOS和Android原生App。初期仅支持iOS平台,同年9月份,该开源项目同时支持Android平台。
原理:
在JavaScript中用React抽象操作系统原生的UI组件,代替DOM元素来渲染,比如以<View>取代<div>,以<Image>替代<im g>等。
优点:
能够用JavaScript脚本就可以写出App的界面,从前端角度而言,React Native跨平台特性,不要开发者深入的了解各平台就能开发一款高效App。
组件化:
Props(当前组件只读):
State(当前组件私有):
当 state 更新之后,组件就会重新渲染自己。
render() 方法依赖于 this.props 和 this.state ,框架会确保渲染出来的 UI 界面总是与输入( this.props 和 this.state )保持一致。
组件生命周期
1.Mounting:已插入真实 DOM
2.Updating:正在被重新渲染
3.Unmounting:已移出真实 DOM
Mounting(装载):
getInitialState(): 在组件挂载之前调用一次。返回值将会作为 this.state 的初始值。
componentWillMount():服务器端和客户端都只调用一次,在初始化渲染执行之前立刻调用。
componentDidMount():在初始化渲染执行之后立刻调用一次,仅客户端有效(服务器端不会调用)。
Updating (更新):
componentWillReceiveProps(object nextProps): 在组件接收到新的 props 的时候调用。在初始化渲染的时候,该方法不会调用。用此函数可以作为 react 在 prop 传入之后, render() 渲染之前更新 state 的机会。老的 props 可以通过 this.props 获取到。
shouldComponentUpdate(object nextProps, object nextState): 在接收到新的 props 或者 state,将要渲染之前调用。该方法在初始化渲染的时候不会调用。如果确定新的 props 和 state 不会导致组件更新,则此处应该 返回 false。(PS:重写此方法可以根据实际情况,来灵活的控制组件当 props 和 state 发生变化时是否要重新渲染组件。)
componentWillUpdate(object nextProps, object nextState):在接收到新的 props 或者 state 之后,render() 渲染之前立刻调用。在初始化渲染的时候该方法不会被调用。使用该方法做一些更新之前的准备工作。
注意:你不能在该方法中使用 this.setState()。如果需要更新 state 来响应某个 prop 的改变,请使用 componentWillReceiveProps。
componentDidUpdate(object prevProps, object prevState): 在组件的更新已经同步到 DOM 中之后立刻被调用。该方法不会在初始化渲染的时候调用。使用该方法可以在组件更新之后操作 DOM 元素。
Unmounting(移除):
componentWillUnmount:在组件从 DOM 中移除的时候立刻被调用。在该方法中执行任何必要的清理,比如无效的定时器,或者清除在 componentDidMount 中创建的 DOM 元素。
图片引用
<Image source={require('./my-icon.png')} />
如果你有my-icon.ios.png和my-icon.android.png,Packager就会根据平台而选择不同的文件。
你还可以使用@2x,@3x这样的文件名后缀,来为不同的屏幕精度提供图片。比如下面这样的代码结构:
.
├── button.js
└── img
├── check@2x.png
└── check@3x.png
静态图片资源
<Image source={require('./img/check.png')} />
Packager会打包所有的图片并且依据屏幕精度提供对应的资源。譬如说,iPhone 5s会使用check@2x.png,而Nexus 5上则会使用check@3x.png。如果没有图片恰好满足屏幕分辨率,则会自动选中最接近的一个图片。
网络图片
<Image source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}}
style={{width: 400, height: 400}} />
混合App的图片资源
<Image source={{uri: 'app_icon'}} style={{width: 40, height: 40}} />
注意:这一做法并没有任何安全检查。你需要自己确保图片在应用中确实存在,而且还需要指定尺寸。
通过嵌套来实现背景图片
return (
<Image source={...}>
<Text>Inside</Text>
</Image>
);
导航 React Navigation
import MainScreenfrom './src/MainScreen';
import ProfileScreenfrom './src/ProfileScreen';
import {
StackNavigator,
} from 'react-navigation';
const App = StackNavigator({
Main: {screen: MainScreen},
Profile: {screen: ProfileScreen},
});
class MainScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',
};
render() {
const { navigate } = this.props.navigation;
return (
<Button
title="Go to Jane's profile"
onPress={() =>
navigate('Profile', { name: 'Jane' });
}
/>
);
}
}
触摸事件
render() {
return (
<TouchableHighlight onPress={this._onPressButton}> // onLongPress
<Text>Button</Text>
</TouchableHighlight>
);
}
原生按钮:
一般来说,你可以使用TouchableHighlight来制作按钮或者链接。注意此组件的背景会在用户手指按下时变暗。
在Android上还可以使用TouchableNativeFeedback,它会在用户手指按下时形成类似墨水涟漪的视觉效果。
TouchableOpacity会在用户手指按下时降低按钮的透明度,而不会改变背景的颜色。
如果你想在处理点击事件的同时不显示任何视觉反馈,则需要使用TouchableWithoutFeedback。
PanResponder
this.panResponder = PanResponder.create(
{
onStartShouldSetPanResponder: (evt, gestureState) => true,
onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
onMoveShouldSetPanResponder: (evt, gestureState)=> true,
onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
onPanResponderGrant: (evt, gestureState)=>{
this.setState({
initY: gestureState.y0
});
},
onPanResponderMove: (evt, gestureState)=>{},
onPanResponderRelease: (evt, gestureState)=>{
slideEvent(gestureState.moveY);
}
}
)