React Native使你能夠在Javascript和React的基礎(chǔ)上獲得完全一致的開(kāi)發(fā)體驗(yàn),構(gòu)建世界一流的原生APP。
React Native著力于提高多平臺(tái)開(kāi)發(fā)的開(kāi)發(fā)效率 —— 僅需學(xué)習(xí)一次,編寫任何平臺(tái)。(Learn once, write anywhere)
Facebook已經(jīng)在多項(xiàng)產(chǎn)品中使用了React Native,并且將持續(xù)地投入建設(shè)React Native。
原生組件#
使用React Native,你可以使用標(biāo)準(zhǔn)的平臺(tái)組件,例如iOS的UITabBar或安卓的Drawer。
這使你的app獲得平臺(tái)一致的視覺(jué)效果和體驗(yàn),并且獲得最佳的性能和流暢性。
使用對(duì)應(yīng)的React component,就可以輕松地把這些原生組件整合到你的React Native應(yīng)用中,
例如TabBarIOS和DrawerLayoutAndroid。
// iOS
var React = require('react-native');
var { TabBarIOS, NavigatorIOS } = React;
var App = React.createClass({
render: function() {
return (
<TabBarIOS>
<TabBarIOS.Item title="React Native" selected={true}>
<NavigatorIOS initialRoute={{ title: 'React Native' }} />
</TabBarIOS.Item>
</TabBarIOS>
);
},
});
// Android
var React = require('react-native');
var { DrawerLayoutAndroid, ProgressBarAndroid } = React;
var App = React.createClass({
render: function() {
return (
<DrawerLayoutAndroid
renderNavigationView={() => <Text>React Native</Text>}>
<ProgressBarAndroid />
</DrawerLayoutAndroid>
);
},
});
異步執(zhí)行#
在Javascript代碼和原生平臺(tái)之間的所有操作都是異步執(zhí)行的,并且原生模塊還可以根據(jù)需要?jiǎng)?chuàng)建新的線程。這意味著你可以在主線程解碼圖片,然后在后臺(tái)將它保存到磁盤,或者在不阻塞UI的情況下計(jì)算文字大小和界面布局等等。所以React Native開(kāi)發(fā)的app天然具備流暢和反應(yīng)靈敏的優(yōu)勢(shì)。Javascript和原生代碼之間的通訊是完全可序列化的,這使得我們可以借助Chrome開(kāi)發(fā)者工具去調(diào)試應(yīng)用,而不論應(yīng)用運(yùn)行在模擬器還是真機(jī)上。
參見(jiàn)調(diào)試

觸摸事件處理#
React Native實(shí)現(xiàn)了一個(gè)強(qiáng)大的觸摸事件處理系統(tǒng),可以在復(fù)雜的View層次關(guān)系下正確地處理觸摸事件。同時(shí)還提供了高度封裝的組件如TouchableHighlight等,可以直接嵌入到ScrollView或者其它的元素中,無(wú)需額外配置。
// iOS & Android
var React = require('react-native');
var { ScrollView, TouchableHighlight, Text } = React;
var TouchDemo = React.createClass({
render: function() {
return (
<ScrollView>
<TouchableHighlight onPress={() => console.log('pressed')}>
<Text>Proper Touch Handling</Text>
</TouchableHighlight>
</ScrollView>
);
},
});
彈性盒(Flexbox)和樣式#
控制view的布局應(yīng)當(dāng)簡(jiǎn)單易行,這就是為什么React Native從web中借鑒了Flexbox模型。Flexbox讓大多數(shù)常見(jiàn)的UI布局構(gòu)建變得簡(jiǎn)單(譬如帶有外襯margin和內(nèi)襯padding,且堆疊在一起的多個(gè)矩形)。React Native還支持多種常見(jiàn)的web樣式,例如fontWeight等。抽象樣式表提供了一個(gè)高性能的機(jī)制來(lái)聲明所有的樣式和布局,并且可以直接應(yīng)用到你的組件中。
// iOS & Android
var React = require('react-native');
var { Image, StyleSheet, Text, View } = React;
var ReactNative = React.createClass({
render: function() {
return (
<View style={styles.row}>
<Image
source={{uri: 'http://facebook./react/img/logo_og.png'}}
style={styles.image}
/>
<View style={styles.text}>
<Text style={styles.title}>
React Native
</Text>
<Text style={styles.subtitle}>
Build high quality mobile apps using React
</Text>
</View>
</View>
);
},
});
var styles = StyleSheet.create({
row: { flexDirection: 'row', margin: 40 },
image: { width: 40, height: 40, marginRight: 10 },
text: { flex: 1, justifyContent: 'center'},
title: { fontSize: 11, fontWeight: 'bold' },
subtitle: { fontSize: 10 },
});
兼容通用標(biāo)準(zhǔn)#
React Native致力于改進(jìn)視圖代碼的編寫方式。除此之外,我們還吸納了web生態(tài)系統(tǒng)中的通用標(biāo)準(zhǔn),并在必要的時(shí)候?yàn)檫@些API提供兼容層。如此一來(lái),npm上的許多庫(kù)就可以在React Native中直接使用。這樣的兼容層有XMLHttpRequest, window.requestAnimationFrame, navigator.geolocation等。我們還在努力增加更多的API,并且十分歡迎開(kāi)源社區(qū)進(jìn)行貢獻(xiàn)。
// iOS (Android的地理定位也即將支持)
var React = require('react-native');
var { Text } = React;
var GeoInfo = React.createClass({
getInitialState: function() {
return { position: 'unknown' };
},
componentDidMount: function() {
navigator.geolocation.getCurrentPosition(
(position) => this.setState({position}),
(error) => console.error(error)
);
},
render: function() {
return (
<Text>
Position: {JSON.stringify(this.state.position)}
</Text>
);
},
});
擴(kuò)展性#
使用React Native,無(wú)需編寫一行原生代碼即可創(chuàng)造一款不錯(cuò)的app。盡管如此,使用自定義的原生視圖和模塊來(lái)擴(kuò)展React Native也非常容易 —— 這意味著你現(xiàn)有的所有工作都可以被復(fù)用,你喜歡的各種原生庫(kù)都可以被導(dǎo)入。
創(chuàng)建iOS模塊#
想要?jiǎng)?chuàng)建一個(gè)iOS模塊,只需要?jiǎng)?chuàng)建一個(gè)接口,實(shí)現(xiàn)RCTBridgeModule協(xié)議,然后把你想在Javascript中使用的任何方法用RCT_EXPORT_METHOD包裝。最后,再用RCT_EXPORT_MODULE導(dǎo)出整個(gè)模塊即可。
// Objective-C
#import "RCTBridgeModule.h"
@interface MyCustomModule : NSObject <RCTBridgeModule>
@end
@implementation MyCustomModule
RCT_EXPORT_MODULE();
// Available as NativeModules.MyCustomModule.processString
RCT_EXPORT_METHOD(processString:(NSString *)input callback:(RCTResponseSenderBlock)callback)
{
callback(@[[input stringByReplacingOccurrencesOfString:@"Goodbye" withString:@"Hello"]]);
}
@end
// JavaScript
var React = require('react-native');
var { NativeModules, Text } = React;
var Message = React.createClass({
getInitialState() {
return { text: 'Goodbye World.' };
},
componentDidMount() {
NativeModules.MyCustomModule.processString(this.state.text, (text) => {
this.setState({text});
});
},
render: function() {
return (
<Text>{this.state.text}</Text>
);
}
});
創(chuàng)建iOS View#
若想自定義iOS View,可以這樣來(lái)做:首先繼承RCTViewManager類,然后實(shí)現(xiàn)一個(gè)-(UIView *)view方法,并且使用RCT_EXPORT_VIEW_PROPERTY宏導(dǎo)出屬性。最后用一個(gè)Javascript文件連接并進(jìn)行包裝。
// Objective-C
#import "RCTViewManager.h"
@interface MyCustomViewManager : RCTViewManager
@end
@implementation MyCustomViewManager
RCT_EXPORT_MODULE()
- (UIView *)view
{
return [[MyCustomView alloc] init];
}
RCT_EXPORT_VIEW_PROPERTY(myCustomProperty, NSString);
@end
// JavaScript
var React = require('react-native');
var { requireNativeComponent } = React;
class MyCustomView extends React.Component {
render() {
return <NativeMyCustomView {...this.props} />;
}
}
MyCustomView.propTypes = {
myCustomProperty: React.PropTypes.oneOf(['a', 'b']),
};
var NativeMyCustomView = requireNativeComponent('MyCustomView', MyCustomView);
module.exports = MyCustomView;
創(chuàng)建Android模塊#
同樣的,Android也支持自定義擴(kuò)展。僅僅是方法略有差異。
創(chuàng)建一個(gè)基礎(chǔ)的安卓模塊,需要先創(chuàng)建一個(gè)繼承自ReactContentBaseJavaModule的類,然后使用@ReactMethod標(biāo)注(Annotation)來(lái)標(biāo)記那些你希望通過(guò)Javascript來(lái)訪問(wèn)的方法。最后,需要在ReactPackage中注冊(cè)這個(gè)模塊。
// Java
public class MyCustomModule extends ReactContextBaseJavaModule {
// Available as NativeModules.MyCustomModule.processString
@ReactMethod
public void processString(String input, Callback callback) {
callback.invoke(input.replace("Goodbye", "Hello"));
}
}
// JavaScript
var React = require('react-native');
var { NativeModules, Text } = React;
var Message = React.createClass({
getInitialState() {
return { text: 'Goodbye World.' };
},
componentDidMount() {
NativeModules.MyCustomModule.processString(this.state.text, (text) => {
this.setState({text});
});
},
render: function() {
return (
<Text>{this.state.text}</Text>
);
}
});
創(chuàng)建Android View#
創(chuàng)建自定義的Android View,首先定義一個(gè)繼承自SimpleViewManager的類,并實(shí)現(xiàn)createViewInstance和getName方法,然后使用@UIProp標(biāo)注導(dǎo)出屬性,最后用一個(gè)Javascript文件連接并進(jìn)行包裝。
// Java
public class MyCustomViewManager extends SimpleViewManager<MyCustomView> {
private static final String REACT_CLASS = "MyCustomView";
@UIProp(UIProp.Type.STRING)
public static final String PROP_MY_CUSTOM_PROPERTY = "myCustomProperty";
@Override
public String getName() {
return REACT_CLASS;
}
@Override
protected MyCustomView createViewInstance(ThemedReactContext reactContext) {
return new MyCustomView(reactContext);
}
@Override
public void updateView(MyCustomView view, CatalystStylesDiffMap props) {
super.updateView(view, props);
if (props.hasKey(PROP_MY_CUSTOM_PROPERTY)) {
view.setMyCustomProperty(props.getString(PROP_MY_CUSTOM_PROPERTY));
}
}
}
// JavaScript
var React = require('react-native');
var { requireNativeComponent } = React;
class MyCustomView extends React.Component {
render() {
return <NativeMyCustomView {...this.props} />;
}
}
MyCustomView.propTypes = {
myCustomProperty: React.PropTypes.oneOf(['a', 'b']),
};
var NativeMyCustomView = requireNativeComponent('MyCustomView', MyCustomView);
module.exports = MyCustomView;
友情鏈接:Node.js中文網(wǎng) 更多
|