一、前言
最近开新项目,准备尝试一下 ReactNative,所以前期做了一些调研工作,ReactNative 的优点非常的明显,可以做到跨平台,除了少部分 UI 效果可能需要对不同的平台进行单独适配,其中的核心逻辑代码,都是可以重用的。
二、优势
React Native使你只使用JavaScript也能编写原生移动应用。 它在设计原理上和React一致,通过声明式的组件机制来搭建丰富多彩的用户界面。
React Native产出的并不是“网页应用”, 或者说“HTML5应用”,又或者“混合应用”。 最终产品是一个真正的移动应用,从使用感受上和用Objective-C或Java编写的应用相比几乎是无法区分的。 React Native所使用的基础UI组件和原生应用完全一致。
React Native让你可以快速迭代开发应用。 比起传统原生应用漫长的编译过程,现在你可以在瞬间刷新你的应用。
React Native完美兼容使用Objective-C、Java或是Swift编写的组件。 如果你需要针对应用的某一部分特别优化,中途换用原生代码编写也很容易。
React Native 看起来很像 React,只不过其基础组件是原生组件而非 web 组件。要理解 React Native 应用的基本结构,首先需要了解一些基本的 React 的概念,比如 JSX 语法、组件、state状态以及props属性。
三、 示例
import React, { Component } from 'react';
import { View,Text } from 'react-native';
export default class HelloWorldApp extends Component{
render() {
return (
<View style={{flex:1,justifyContent:'center',alignItems:'center'}}>
<Text>hello,chenfan </Text>
</View>
);
}
}
ES2015 (也叫作 ES6)——这是一套对 JavaScript 的语法改进的官方标准。但是这套标准目前还没有在所有的浏览器上完整实现,所以目前而言 web 开发中还很少使用。React Native 内置了对 ES2015 标准的支持,你可以放心使用而无需担心兼容性问题。上面的示例代码中的import、from、class、extends、以及() =>箭头函数等新语法都是 ES2015 中的特性。
示例中的这一行<View><Text>Hello world!</Text></View>恐怕很多人看起来也觉得陌生。这叫做 JSX——是一种在 JavaScript 中嵌入 XML 结构的语法。很多传统的应用框架会设计自有的模板语法,让你在结构标记中嵌入代码。React 反其道而行之,设计的 JSX 语法却是让你在代码中嵌入结构标记。初看起来,这种写法很像 web 上的 HTML,只不过使用的并不是 web 上常见的标签如<div>或是<span>等,这里我们使用的是 React Native 的组件。
三、使用
- 自定义组件
import React,{Component} from 'react';
import {Text,View} from 'react-native';
class Greeting extends Component{
render(): React.ReactNode {
return (
<Text>Hello,{this.props.xs}</Text>
);
}
}
export default class LotsOfGreetings extends Component{
render(): React.ReactNode {
return (
<View style={{alignItems:'center'}}>
<Greeting xs='Text 111'/>
<Greeting xs='Text 222'/>
<Greeting xs='Text 333'/>
<Greeting xs='Text 444'/>
<Greeting xs='Text 555'/>
<Greeting xs='Text 666'/>
<Greeting xs='Text 777'/>
</View>
);
}
}
- State(状态)
class Blink extends Component{
state = {isShowingText:true};
componentDidMount(): void {
setInterval(() => {
this.setState({
isShowingText:!this.state.isShowingText
});
},1000);
}
render(): React.ReactNode {
if (!this.state.isShowingText){
return null;
}
return (
<Text>{this.props.text}</Text>
);
}
}
- CSS样式
import React,{Component} from 'react';
import {View,Text,StyleSheet} from 'react-native';
const styles = StyleSheet.create({
bigBlue:{
color:'blue',
fontWeight: 'bold',
fontSize:30,
},
red: {
color: 'red',
}
});
export default class LotsOfStyles extends Component{
render(): React.ReactNode {
return (
<View>
<Text style={styles.bigBlue}>test1</Text>
<Text style={styles.red}>test1</Text>
<Text style={styles.bigBlue}>test1</Text>
<Text style={styles.red}>test1</Text>
</View>
);
}
}
- 指定宽高
import React,{Component} from 'react';
import {View} from 'react-native';
export default class FixedDimensionsBasics extends Component{
render(): React.ReactNode {
return (
<View style={{width:50,height:50,backgroundColor:'red'}}></View>,
<View style={{width:100,height:100,backgroundColor:'blue'}}></View>,
<View style={{width:150,height:150,backgroundColor:'gray'}}></View>
);
}
}
- 弹性(Flex)宽高
import React,{Component} from 'react';
import {View} from 'react-native';
export default class FlexDimensionsBasics extends Component{
render(): React.ReactNode {
return (
<View style={{flex:1}}>
<View style={{flex:1,backgroundColor:'blue'}}></View>
<View style={{flex:1,backgroundColor:'red'}}></View>
<View style={{flex:1,backgroundColor:'gray'}}></View>
</View>
);
}
}
- Flexbox布局
import React,{Component} from 'react';
import {View} from 'react-native';
export default class FlexDirectionBasics extends Component{
render(): React.ReactNode {
return (
<View style={{flex:1,flexDirection:'row'}}>
<View style={{width:50,height:50,backgroundColor:'red'}}></View>
<View style={{width:50,height:50,backgroundColor:'blue'}}></View>
<View style={{width:50,height:50,backgroundColor:'gray'}}></View>
</View>
);
}
}
- Justify Content
import React,{Component} from 'react';
import {View} from 'react-native';
export default class JustifyContentBasics extends Component{
render(): React.ReactNode {
return (
<View style={{
flex:1,
flexDirection:'column',
justifyContent:'space-between',
}}>
<View style={{width:50,height:50,backgroundColor:'blue'}}></View>
<View style={{width:50,height:50,backgroundColor:'gray'}}></View>
<View style={{width:50,height:50,backgroundColor:'red'}}></View>
</View>
);
}
}
- Align Items
import React,{Component} from 'react';
import {View} from 'react-native';
export default class AlignItemsBasics extends Component{
render(): React.ReactNode {
return (
<View style={{
flex:1,
flexDirection:'column',
justifyContent:'center',
alignItems:'stretch',
}}>
<View style={{width:50,height:50,backgroundColor:'red'}}></View>
<View style={{width:50,height:50,backgroundColor:'blue'}}></View>
<View style={{width:50,height:50,backgroundColor:'gray'}}></View>
</View>
);
}
}
- 处理文本输入
import React,{Component} from 'react';
import {View,TextInput,Text} from 'react-native';
export default class PizzaTranslator extends Component{
state ={
text:''
};
render(): React.ReactNode {
return (
<View style={{padding:10}}>
<TextInput
style={{height:440}}
placeholder='sw'
onChangeText={(text) => this.setState({text})}
value={this.state.text}
/>
<Text style={{padding: 10, fontSize: 42}}>
{this.state.text.split(' ').map((word) => word && '🍕').join(' ')}
</Text>
</View>
);
}
}
- 处理触摸事件
import React,{Component} from 'react';
import {Alert,View,StyleSheet,Button} from 'react-native';
const styles = StyleSheet.create({
container:{
flex:1,
justifyContent:'center',
},
buttonContainer:{
margin:20
},
alternativeLayoutButtonContainer:{
margin: 20,
flexDirection:'row',
justifyContent: 'space-between'
}
});
export default class ButtonBasics extends Component{
_onPressButton() {
Alert.alert('testssss')
}
render(): React.ReactNode {
return (
<View style={styles.container}>
<View style={styles.buttonContainer}>
<Button
onPress={this._onPressButton}
title='pppppp'
/>
</View>
<View style={styles.buttonContainer}>
<Button
onPress={this._onPressButton}
title="Press Me"
color="#841584"
/>
</View>
</View>
);
}
}
- 使用滚动视图
import React,{Component} from 'react';
import {ScrollView,Text,Image} from 'react-native';
export default class IScrolledDownAndWhatHappenedNextShockedMe extends Component{
render(): React.ReactNode {
return (
<ScrollView>
<Text style={{fontSize:96}}>Scroll me plz</Text>
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Text style={{fontSize:96}}>If you like</Text>
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Text style={{fontSize:96}}>Scrolling down</Text>
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Text style={{fontSize:96}}>What's the best</Text>
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Text style={{fontSize:96}}>Framework around?</Text>
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Image source={{uri: "https://facebook.github.io/react-native/img/favicon.png", width: 64, height: 64}} />
<Text style={{fontSize:80}}>React Native</Text>
</ScrollView>
);
}
}
- 使用长列表
import React,{Component} from 'react';
import {View,StyleSheet,FlatList,Text} from 'react-native';
const styles=StyleSheet.create({
container: {
flex: 1,
paddingTop: 22
},
item: {
padding: 10,
fontSize: 18,
height: 44,
},
});
export default class FlatListBasics extends Component{
render(): React.ReactNode {
return (
<View style={styles.container}>
<FlatList
data={[
{key:'1'},
{key:'1'},
{key:'1'},
{key:'1'},
{key:'1'},
{key:'1'},
{key:'1'},
{key:'1'},
]}
renderItem={({item}) =><Text style={styles.item}>{item.key}</Text>}
/>
</View>
);
}
}
import React,{Component} from 'react';
import {View,StyleSheet,SectionList,Text} from 'react-native';
const styles=StyleSheet.create({
container: {
flex: 1,
paddingTop: 22
},
sectionHeader: {
paddingTop: 2,
paddingLeft: 10,
paddingRight: 10,
paddingBottom: 2,
fontSize: 14,
fontWeight: 'bold',
backgroundColor: 'rgba(247,247,247,1.0)',
},
item: {
padding: 10,
fontSize: 18,
height: 44,
},
});
export default class SectionListBasics extends Component{
render(): React.ReactNode {
return (
<View style={{backgroundColor: 'red' ,width:1000,height: 2000}}>
<SectionList
sections={[
{title:'11',data:['ssssss','22222']},
{title:'11',data:['ssssss','22222']}
]}
renderItem={({item}) =><Text style={styles.item}>{item}</Text>}
renderSectionHeader={({section}) =><Text style={styles.sectionHeader}>{section.title}</Text>}
keyExtractor={(item,index) =>index}
/>
</View>
);
}
}
- 网络
import React,{Component} from 'react';
import {View,ActivityIndicator,FlatList,Text} from 'react-native';
export default class FetchExample extends Component{
constructor(props) {
super(props);
this.state={isLoading:true}
}
componentDidMount(): void {
return fetch('https://facebook.github.io/react-native/movies.json')
.then((response) =>response.json())
.then((responseJson) => {
console.log(responseJson);
this.setState({
isLoading:false,
dataSource:responseJson.movies,
},function () {
})
})
.catch((error => {
console.log(error);
}))
}
render(): React.ReactNode {
if (this.state.isLoading) {
return (
<View style={{flex:1,padding:20}}>
<ActivityIndicator/>
</View>
);
}
return(
<View style={{flex: 1,padding: 20}}>
<FlatList
data={this.state.dataSource}
renderItem={({item}) => <Text>{item.releaseYear}</Text>}
keyExtractor={(item,index) => item.id}
/>
</View>
);
}
}
四、组件
- 基础组件
View、 Text Image、 TextInput、 ScrollView、 StyleSheet - 交互控件
Button、Picker、Slider、Switch - 列表视图
Flatlist、SectionList - iOS 独有的组件和 API
ActionSheetIOS、AlertIOS、DatePickerIOS、ImagePickerIOS、ProgressViewIOS、PushNotificationIOS、SegmentedControlIOS、TabBarIOS - 其他
ActivityIndicator、Alert、Animated、CameraRoll、Clipboard、Dimensions、KeyboardAvoidingView、Linking、Modal、PixelRatio、RefreshControl、StatusBar、WebView
五、特定平台代码
- Platform 模块
import React,{Component} from 'react';
import {Platform,StyleSheet,View} from 'react-native';
const styles=StyleSheet.create({
container:{
flex:1,
...Platform.select({
ios:{
backgroundColor:'red'
},
android:{
backgroundColor: 'blue'
}
})
}
});
export default class ss extends Component{
render(): React.ReactNode {
return (
<View style={styles.container}>
</View>
);
}
}
import { Platform, StyleSheet } from "react-native";
const styles = StyleSheet.create({
height: Platform.OS === "ios" ? 200 : 100
});
- 检测 iOS 版本
Platform.Version
- 图片
// 静态图片资源
<Image source={require('./address_down@3X.png')}></Image>
// 网络图片
<Image
source={{
uri: 'https://facebook.github.io/react/logo-og.png',
method: 'POST',
headers: {
Pragma: 'no-cache',
},
body: 'Your Body goes here',
}}
style={{width: 400, height: 400}}
/>
// Uri 数据图片
// 请记得指定宽高!
<Image
style={{
width: 51,
height: 51,
resizeMode: 'contain',
}}
source={{
uri:
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg==',
}}
/>
// 缓存控制(仅 iOS)
- 动画
六、调试
React Native 在 iOS 模拟器上支持一些快捷键操作,具体会在下文中描述。要使用快捷键请务必确保模拟器的 Hardware 菜单中,Keyboard 选项下的"Connect Hardware Keyboard"处于开启状态,否则按键是没有响应的。
Command⌘ + D
红屏错误
黄屏警告
网友评论