React Native


# 简介

React Native (简称 RN) 是 Facebook 于 2015 年 4 月开源的跨平台移动应用开发框架,是 Facebook 早先开源的 JS 框架 React 在原生移动应用平台的衍生产物,支持 iOS 和安卓 两大平台。RN 使用 Javascript 语言,类似于 HTML 的 JSX,以及 CSS 来开发移动应用,因此熟悉 Web 前端开发的技术人员只需很少的学习就可以进入移动应用开发领域。

# React Native 适合哪些场景

没有完美的跨端技术,只有适合的场景。脱离适用场景去谈跨端技术没有什么意义 。

# 适合业务更新迭代较快的团队

React Native 上手成本较低。对前端同学来说,React Native 和前端技术生态重合度很高, 学习成本很低 ;对客户端同学来说,React Native 省去了大量的编译耗时 ,并且自带跨端光环, 一份源码可以同时编译成 Android 和 iOS 原生应用,并发布到安卓和苹果应用商店上 。
所以,在一些业务迭代快的团队中,使用 React Native 跨端方案 不仅能够节约开发成本,还能带来接近原生的体验和性能 。

# 既要支持动态更新,又要支持复杂业务的场景

在国内,无论大公司、小公司都钟情于 应用的动态更新 。因为动态更新 能降低产品的试错成本 。如果产品策略有调整,可以立马上线,线上有小问题也可以快速修复。但能够 既满足动态更新,又能跨端,还能满足复杂业务需求的只有 JavaScript 语言 。
目前几个主流的跨端框架,除了 React Native 之外,还有小程序、Weex、Flutter。但小程序只能让你的应用运行在别人的 App 上,Weex 最终未能大规模流行起来,而 Flutter 使用的语言是 Dart 而非 JavaScript,并不能很好支持动态更新 。
换句话说,除了基于 JavaScript 的自研框架外, 目前能够既支持动态更新,又支持复杂业务的主流移动跨端框架只有使用 JavaScript 开发的 React Native 。

# 为什么选择 React Native 做你的跨端方案

# React Native 是一个非常流行的跨端框架,开发者认可度很高。

react-native 框架每周的下载次数,已经从 5 年前的不到 10 万次,到现在超过了 80 万次,5 年时间翻了 8 倍之多。
对于个人而言,强大的生态意味着很多功能都不用自己写,从社区拿来用就行,这极大地降低了开发成本。你可以在社区中选择最适合你业务的技术工具,比如状态管理、路由、动画、工具库和原生扩展等等。对于企业来说,使用 React Native 这类成熟框架开发移动应用成本更低,风险也更低,企业也更愿意招聘相关开发者。

# React Native 能让你得到技术上的延伸

如果你是一个前端工程师,已经掌握 JavaScript、React 的相关技术,那么对 React Native 的学习,可以让你了解到那些独属于 Android 和 iOS 原生平台的特性。
比如,你可以亲手尝试使用 WebView 容器来加载 Web 页面,甚至你还可以用 WebView 中的 JavaScript 去调用 React Native 中的 JavaScript,把 Native 暴露给 React Native 的支付能力再暴露给 Web,这样你能更加深刻地体会到 Hybrid 的实现原理。

# 入门基础

# 函数式组件与 Class 组件

你可以在 React 中使用函数式组件或 Class 组件。最开始只有 Class 组件能够使用 state ,但自从有了 React Hooks API, 你可以为函数组件添加 state 和很多其它的功能。
Hooks API 是 React Native 0.59 提供的新特性,Hooks 是一种面向未来的编写 React 组件的方式,因此 推荐优先使用函数组件 。

  • 函数式组件
    flex布局再RN中垂直的,这里的justifyContent代表垂直方向,alignItems代表水平方向

    import React from "react";
    import { Text, View } from "react-native";
    const HelloWorldApp = () => {
      return (
        <View
          style={{
            flex: 1,
            justifyContent: "center",
            alignItems: "center",
          }}
        >
          <Text>Hello, world!</Text>
        </View>
      );
    };
    export default HelloWorldApp;
  • Class 组件

    import React, { Component } from "react";
    import { Text, View } from "react-native";
    class HelloWorldApp extends Component {
      render() {
        return (
          <View
            style={{
              flex: 1,
              justifyContent: "center",
              alignItems: "center",
            }}
          >
            <Text>Hello, world!</Text>
          </View>
        );
      }
    }
    export default HelloWorldApp;

# 原生组件与核心组件

# 原生组件

在 Android 开发中是使用 Kotlin 或 Java 来编写视图;在 iOS 开发中是使用 Swift 或 Objective-C 来编写视图。在 React Native 中,则使用 React 组件通过 JavaScript 来调用这些视图。在运行时,React Native 为这些组件创建相应的 Android 和 iOS 视图。由于 React Native 组件就是对原生视图的封装,因此使用 React Native 编写的应用外观、感觉和性能与其他任何原生应用一样。我们将这些平台支持的组件称为 原生组件 。

React Native 允许您为 Android 和 iOS 构建自己的 Native Components(原生组件),以满足您开发应用程序的独特需求。

React Native 还包括一组基本的,随时可用的原生组件,您可以使用它们来构建您的应用程序。这些是 React Native 的 核心组件 。

# 核心组件

React Native 具有许多核心组件,从表单控件到活动指示器,应有尽有。比如: <View> 在 Android 中为 <ViewGroup> ,在 IOS 中为 <UIView>

  • 案例 1:使用基本组件

    import React from "react";
    import { View, Text, Image, ScrollView, TextInput } from "react-native";
    
    const App = () => {
      return (
        // ScrollView:可以包含多个组件和视图的通用滚动容器,对应Web中的div
        <ScrollView>
        // Text:对应Web中的p
          <Text>Some text</Text>
          // View:对应不滚动的div
          <View>
            <Text>Some more text</Text>
            // 图片,对应Web中的img
            <Image
              source={{
                uri: "https://reactnative.dev/docs/assets/p_cat2.png",
              }}
              style={{ width: 200, height: 200 }}
            />
          </View>
          // 输入框,defaultValue是默认值
          // TextInput:对应Web中的<input type="text">
          <TextInput
            style={{
              height: 40,
              borderColor: "gray",
              borderWidth: 1,
            }}
            defaultValue="You can type in me"
          />
        </ScrollView>
      );
    };
    
    export default App;
  • 案例 2:使用 state

    import React, { useState } from "react";
    import { Button, Text, View } from "react-native";
    
    const Cat = (props) => {
      const [isHungry, setIsHungry] = useState(true);
    
      return (
        <View>
          <Text>
            I am {props.name}, and I am {isHungry ? "hungry" : "full"}!
          </Text>
          <Button
            onPress={() => {
              setIsHungry(!isHungry);
            }}
            title={isHungry ? "Pour me some milk, please!" : "Thank you!"}
          />
        </View>
      );
    };
    
    const Cafe = () => {
      return (
        <>
          <Cat name="Munkustrap" />
          <Cat name="Spot" />
        </>
      );
    };
    
    export default Cafe;
  • 案例 3:使用 TextInput

    import React, { useState } from "react";
    import { Text, TextInput, View } from "react-native";
    
    export default function PizzaTranslator() {
      const [text, setText] = useState("");
      // onChangeText的属性,此属性接受一个函数,而此函数会在文本变化时被调用。另外还有一个名为onSubmitEditing的属性,会在文本被提交后(用户按下软键盘上的提交键)调用。
      return (
        <View style={{ padding: 10 }}>
          <TextInput
            style={{ height: 40 }}
            placeholder="Type here to translate!"
            onChangeText={(text) => setText(text)}
            defaultValue={text}
          />
          <Text style={{ padding: 10, fontSize: 42 }}>
            {text
              .split(" ")
              .map((word) => word && "🍕")
              .join(" ")}
          </Text>
        </View>
      );
    }
  • 案例 4:使用滚动视图

    • ScrollView 是一个通用的可滚动的容器,你可以在其中放入多个组件和视图,而且这些组件并不需要是同类型的。ScrollView 不仅可以垂直滚动,还能水平滚动(通过 horizontal 属性来设置)。

    • 代码

      import React from "react";
      import { Image, ScrollView, Text } from "react-native";
      
      const logo = {
        uri: "https://reactnative.dev/img/tiny_logo.png",
        width: 64,
        height: 64,
      };
      
      export default App = () => (
        <ScrollView horizontal={true}>
          // horizontal={true} 设置为水平滚动,默认为false(垂直滚动)
          <Text style={{ fontSize: 96 }}>Scroll me plz</Text>
          <Image source={logo} />
          <Image source={logo} />
          <Text style={{ fontSize: 96 }}>If you like</Text>
          <Image source={logo} />
          <Image source={logo} />
          <Text style={{ fontSize: 96 }}>Scrolling down</Text>
          <Image source={logo} />
          <Image source={logo} />
          <Text style={{ fontSize: 96 }}>What's the best</Text>
          <Image source={logo} />
          <Image source={logo} />
          <Text style={{ fontSize: 96 }}>Framework around?</Text>
          <Image source={logo} />
          <Image source={logo} />
          <Text style={{ fontSize: 80 }}>React Native</Text>
        </ScrollView>
      );
    • ScrollViews 可以通过使用 pagingEnabled 属性来允许使用滑动手势对视图进行分页,在 Android 上也可以利用 ViewPager 组件水平滑动视图。

    • 在 iOS 上包含单个子元素的 ScrollViews 可以允许用户对内容进行缩放。通过设置 maximumZoomScale 和 minimumZoomScale 两者的属性,您的用户能够利用捏合以及扩大手势来放大或缩小。

    • ScrollView 适合用来显示数量不多的滚动元素。放置在 ScrollView 中的所有组件都会被渲染,哪怕有些组件因为内容太长被挤出了屏幕外。如果你 需要显示较长的滚动列表 ,那么 应该使用功能差不多但性能更好的 FlatList(长列表)组件 。

  • 案例 5:使用长列表
    React Native 提供了几个适用于展示长列表数据的组件,一般而言我们会选用 FlatList 或是 SectionList

    FlatList 组件用于显示一个垂直的滚动列表, 其中的元素之间结构近似而仅数据不同 。

    FlatList 更适于长列表数据,且元素个数可以增删。 和 ScrollView 不同的是,FlatList 并不立即渲染所有元素,而是优先渲染屏幕上可见的元素 。

    FlatList 组件 必须的两个属性 是 data 和 renderItem 。data 是列表的 数据源 ,而 renderItem 则从数据源中逐个解析数据 ,然后返回一个设定好格式的组件来渲染。

    下面的例子创建了一个简单的 FlatList,并预设了一些模拟数据。首先是初始化 FlatList 所需的 data,其中的每一项(行)数据之后都在 renderItem 中被渲染成了 Text 组件,最后构成整个 FlatList。

    • FlatList 代码

      import React from "react";
      import { FlatList, StyleSheet, Text, View } from "react-native";
      
      const styles = StyleSheet.create({
        container: {
          flex: 1,
          paddingTop: 22,
        },
        item: {
          padding: 10,
          fontSize: 18,
          height: 44,
        },
      });
      
      const FlatListBasics = () => {
        return (
          <View style={styles.container}>
            <FlatList
              data={[
                { key: "Devin" },
                { key: "Dan" },
                { key: "Dominic" },
                { key: "Jackson" },
                { key: "James" },
                { key: "Joel" },
                { key: "John" },
                { key: "Jillian" },
                { key: "Jimmy" },
                { key: "Julie" },
              ]}
              renderItem={({ item }) => (
                <Text style={styles.item}>{item.key}</Text>
              )}
            />
          </View>
        );
      };
      
      export default FlatListBasics;

      如果要渲染的是一组 需要分组 的数据, 也许还带有分组标签 的,那么 SectionList 将是个不错的选择

    • SectionList 代码

      import React from "react";
      import { SectionList, StyleSheet, Text, View } 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,
        },
      });
      
      const SectionListBasics = () => {
        return (
          <View style={styles.container}>
            <SectionList
              sections={[
                { title: "D", data: ["Devin", "Dan", "Dominic"] },
                {
                  title: "J",
                  data: [
                    "Jackson",
                    "James",
                    "Jillian",
                    "Jimmy",
                    "Joel",
                    "John",
                    "Julie",
                  ],
                },
              ]}
              // 这里的item是data中的数据
              renderItem={({ item }) => <Text style={styles.item}>{item}</Text>}
              renderSectionHeader={({ section }) => (
                <Text style={styles.sectionHeader}>{section.title}</Text>
              )}
              keyExtractor={(item, index) => index}
            />
          </View>
        );
      };
      
      export default SectionListBasics;

文章作者: Mrr-cxh
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Mrr-cxh !
赏
 上一篇
Next 1.0 Next 1.0
Next是一个React开发框架。它能确保您和您的团队成功地构建 React 应用程序。Next.js 具有同类框架中最佳的“开发人员体验”和许多内置功能。比如:服务端渲染(SSR)和页面级的静态生成(SSG);基于页面的路由系统(并支持动态路由);具有经过优化的预取功能的客户端路由…….Next.js被用于数以万计的网站和Web应用程序,包括许多世界上最大的品牌都在使用Next.js。
2023-02-05
下一篇 
Sentry Sentry
Sentry 是一个开源的实时错误监控的项目,它支持很多端的配置,包括 web 前端、服务器端、移动端及其游戏端。支持各种语言,例如 python、oc、java、node、javascript 等。也可以应用到各种不同的框架上面,如前端框架中的vue 、angular 、react 等最流行的前端框架。
2022-07-12
  目录