React Native

官网

weex、cordova、flutter、react-native、uniapp 对比
https://zhuanlan.zhihu.com/p/103409129

Core Components

文档

最常用的 native 组件

REACT NATIVE UI COMPONENT ANDROID VIEW IOS VIEW WEB ANALOG DESCRIPTION
<View> <ViewGroup> <UIView> A non-scrollling <div> A container that supports layout with flexbox, style, some touch handling, and accessibility controls
<Text> <TextView> <UITextView> <p> Displays, styles, and nests strings of text and even handles touch events
<Image> <ImageView> <UIImageView> <img> Displays different types of images
<ScrollView> <ScrollView> <UIScrollView> <div> A generic scrolling container that can contain multiple components and views
<TextInput> <EditText> <UITextField> <input type="text"> Allows the user to enter text

基本组件 Basic

  • ScrollView: 在 IOS 设置maximumZoomScale & minimumZoomScale可以放大缩小;pagingEnabled实现 scroll 变整页滑动;默认在 layout 实现上 类似 html 的div{flex: 0, maxHeight: 100vh}
  • View
  • Text
  • Image
  • TextInput
  • StyleSheet: StyleSheet.create({ xxx css obj})
  • [ImageBackground]: props as Image, mean as background-image

用户界面 User Interface

  • Button

  • TouchableHighlight: 包裹仅一个 ElementNode,点击后 backgroundColor 加深 建议替代为 Pressable

  • TouchableOpacity: 包裹 children,点击后 backgroundColor 变浅(加大透明度)建议替代为 Pressable

  • TouchableWithoutFeedback: 包裹仅一个 ElementNode,没有交互 styles and effects 建议替代为 Pressable

  • Pressable: 包裹 children,使其(该 tag)类似 button 具有按压事件:onPressIn & onLongPress & onPressOut & onPress

  • Switch

对比 Pressable 和 Touchable

列表 List Views

  • FlatList: <FlatList data={dataArray} renderItem={renderItem} keyExtractor={item => item.id} onPress={fn} /> 内部实现了虚拟列表 virtual-scrolling
  • SectionList: <SectionList renderSectionHeader={renderHeader} sections={dataArrayNested} renderItem={renderItem} keyExtractor={item => item.id} onPress={fn} /> 相比 FlatList 多了 header 和一层分组
  • VirtualizedList:

性能上:因为虚拟列表的原因每次 scroll 都是新的 item render 尽量避免在renderItem中计算;在renderItemComp内尽量拆分 props;renderItemComp extends PureComponent;as simple as possible

安卓特有 Android

  • API - BackHandler: BackHandler.addEventListener('target', function(){ return true/false}) 订阅栈 监听用户后退点击物理按键后退键动作,后 register 的先 trigger return true 即 preventDefault 安卓退出操作
  • DrawerLayoutAndroid: rendered with renderNavigationView and direct children are the main view (where your content goes).
  • API - PermissionsAndroid: const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.CAMERA, optionalObj); if (granted === PermissionsAndroid.RESULTS.GRANTED){...} 所有可选权限
  • API - ToastAndroid: 安卓原生提示冒泡框 ToastAndroid.showWithGravity('msg', ToastAndroid.SHORT, ToastAndroid.CENTER) ,命令式 改 组件式 调用 例子
  • TouchableNativeFeedback: 安卓原生按钮 建议替代为 Pressable

ios 特有 IOS

  • API - ActionSheettIOS: IOS 的下弹选项列 ActionSheetIOS.showActionSheetWithOptions(options, callback)
  • SafeAreaView: 解决 刘海屏等 safe area boundaries 适配问题
  • InputAccessoryView: 一个只在出现输入法的情况下才显示的 toolbar,InputAccessoryView的nativeID 对应 TextInput的inputAccessoryViewID对其进行操作

其他

  • ActivityIndicator: loading icon
  • Alert: Alert.alert(title, message?, buttonsConfigArray?, options?)
  • Animated: using Animated.timing() updates Animated.Value, 例子:const fadeAnim = useRef(new Animated.Value(0)).current; const fadeIn = () => { Animated.timing(fadeAnim, {toValue: 1, duration: 1000}).start() }; const fadeOut = () => { Animated.timing(fadeAnim, {toValue: 0, duration: 1000}).start() }
  • Dimensions: Dimensions.addEventListener("change", ({ window, screen })=>{ setDimensions({ window, screen }) }), Dimensions.get('window').height 这里的 window 更推荐使用useWindowDimensions
  • KeyboardAvoidingView: 当自带输入法出现时,该 view 自动收缩 based on the keyboard height. <KeyboardAvoidingView><TouchableWithoutFeedback onPress={Keyboard.dismiss}>放置需要根据键盘调整位置的组件</TouchableWithoutFeedback></KeyboardAvoidingView> 配合 flex
  • Linking: 对应安卓的Deep Links 和 IOS 的Universal Links,可以根据 url 跳转其他 app
  • Modal:
  • PixelRatio: 返回设备的像素分辨率 和 缩放大小。PixelRatio.getPixelSizeForLayoutSize(layoutSize: number): number 返回PixelRatio.get() * layoutSize把 dp 单位转为 px roundToNearestPixel 相比这个 返回值会 Math.round 取整
  • RefreshControl: 刷新 icon
  • StatusBar: 控制手机顶端的状态栏,显示隐藏和样式 虽然也有 Imperative API 但是不建议使用 因为全局

一些 native 组件可接受的 style 有一定限制

跨端实现

Platform 模块

  • Platform.OS : ‘ios’ / ‘android’
  • Platform.select({key: returnedContent}) : ios / android / native / default
  • Platform.Version :s
  • 文件后缀 自动(即 Platform.select 后台进程实现)识别 ‘XX.ios.js’ / ‘XX.android.js’, import XX from './XX';
    Container.js # picked up by Webpack, Rollup or any other Web bundler
    Container.native.js # picked up by the React Native bundler for both Android and iOS (Metro), Configure your Web bundler to ignore .native.js 减少 bundle 体积
import { Platform, StyleSheet } from "react-native";
const Component = Platform.select({
  ios: () => require("ComponentIOS"),
  android: () => require("ComponentAndroid"),
  native: () => require("ComponentForNative"),
  default: () => require("ComponentForWeb"),
})();

const majorVersionIOS = parseInt(Platform.Version, 10); // 对ios version 取整

return <Component />;
const styles = StyleSheet.create({
  container: {
    height: Platform.OS === "ios" ? 200 : 100, // 'android'
    flex: 1,
    ...Platform.select({
      ios: {
        backgroundColor: "red",
      },
      android: {
        backgroundColor: "green",
      },
      default: {
        // other platforms, web for example
        backgroundColor: "blue",
      },
    }),
  },
});

开发辅助工具

嗯哼

全面屏适配方案:Dimensions.get('window').height + StatusBar.currentHeight& 判断纵横比1.8
https://segmentfault.com/a/1190000021258428
rn 的 fetch


   转载规则


《React Native》 Ryan Who 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
webWorker webWorker
ForewordJavaScript 作为浏览器脚本语言,被定义为了只有单线程的语言,也就是同一时间只能做同一事情。如果 JavaScript 不是单线程,那么就有点棘手了。比如,与用户交互或者对 DOM 进行操作时,在一个线程上修改某个
2021-05-08
下一篇 
React源码拜读 React源码拜读
概览官网 guide React-coreReact 早期口号是 Rethinking Best Practices(重新思考最佳实践)。背靠 Facebook 的 React,从开始起就不缺关注和用户,而且 React 想要做的是用更好的
2021-05-01
  目录