React Native 学习总结:环境搭建、组件使用与架构解析

Viewed 0

ReactNative 学习总结(个人梳理)

本文档旨在系统性地梳理 React Native (简称 RN) 开发的核心知识点,涵盖环境搭建、基础语法、核心组件、API、常用第三方库、状态管理、导航以及架构概览,为开发大型跨平台应用提供参考。

核心特点:React Native 允许使用 React 语法开发原生移动应用,实现 iOS 与 Android 平台代码的复用。值得注意的是,Windows 环境仅支持 Android 端开发,而 macOS 环境可同时开发 iOS 与 Android 应用。

一、开发环境准备

1. Android 开发环境搭建 (Windows/macOS)

  1. 安装 JDK 1.8:需严格匹配此版本。
  2. 安装 Android Studio:从 Android 开发者官网下载安装。
  3. 配置 Android SDK:在 Android Studio 中安装所需的 SDK 平台和工具。
  4. 配置环境变量:设置 ANDROID_HOME 指向 SDK 安装路径,并将 %ANDROID_HOME%/platform-tools%ANDROID_HOME%/emulator%ANDROID_HOME%/tools%ANDROID_HOME%/tools/bin 添加到系统的 PATH 变量中。

2. iOS 开发环境搭建 (仅限 macOS)

iOS 开发需在 macOS 系统下进行,需要安装 Xcode 及其命令行工具。

二、基础语法与核心概念

1. 项目创建

使用 Expo 的现代命令行工具创建新项目:

npx create-expo-app@latest

注意:项目目录路径请避免使用中文或特殊字符,否则可能导致运行错误。

2. 样式设置

  • 布局:默认采用 Flexbox 布局,但主轴方向与 Web CSS 中的 flex 有所不同(默认为纵向 flexDirection: 'column')。
  • 样式声明:样式不会被继承,尺寸单位不能使用 pxvhvw,可以使用百分比。推荐使用 StyleSheet.create 集中定义样式。
  • 样式应用:通过组件的 style 属性应用,支持内联对象、数组(后者样式优先级更高)及 StyleSheet 定义的样式对象。
import {StyleSheet, Text, View} from 'react-native';
const styles = StyleSheet.create({
  container: { flex: 1, backgroundColor: '#fff' },
  text: { fontSize: 16 }
});
function App() {
  return (
    <View style={styles.container}>
      <Text style={styles.text}>Hello World</Text>
    </View>
  );
}

3. 核心组件与常用组件

RN 提供了丰富的内置组件,所有 UI 均由这些组件组合而成。

  • 核心组件:如 ViewTextImageScrollViewTextInput 等,是构建 UI 的基础。
  • 常用功能性组件
    • StatusBar:控制设备顶部状态栏的显示(隐藏、背景色、图标风格)。backgroundColor 属性仅 Android 有效。
    • Switch:滑动开关组件,可自定义滑轨和滑块颜色。
    • ActivityIndicator:加载指示器(旋转图标),可设置大小和颜色。
    • Platform:用于判断当前运行平台 ('ios''android')。
    • Touchable 系列 (TouchableOpacity, TouchableHighlight, TouchableWithoutFeedback):为任何组件添加可点击的包装,提供不同的触摸反馈效果。
    • ScrollView:提供可滚动视图区域。需注意在 Android 上可能需要在内容底部添加一个空 View 以避免滚动到底部被遮挡。
    • SafeAreaView:自动避开刘海屏、状态栏等不安全区域,确保内容完全可见。
    • FlatList:高性能列表组件,适用于长列表数据,支持下拉刷新、上拉加载、列表头尾组件等。
    • SectionList:支持分组标题的列表组件,具备与 FlatList 相似的性能特性和功能。

4. 常用 API

  • Dimensions:用于获取设备屏幕的宽高。
    import { Dimensions } from 'react-native';
    const { width, height } = Dimensions.get('window');
    
  • Animated:用于创建流畅的动画。使用步骤:
    1. 创建动画值:new Animated.Value(初始值)
    2. 将动画值绑定到可动画组件(如 Animated.View)的样式属性上(如 opacity, transform)。
    3. 通过 Animated.timing, Animated.spring 等方法来驱动动画值的变化。

三、常用第三方库集成

1. 网络视图:react-native-webview

用于在应用中嵌入网页。

npx expo install react-native-webview

2. 选择器:@react-native-picker/picker

提供下拉选择器组件。

npx expo install @react-native-picker/picker

3. 轮播/页面切换:react-native-pager-view

实现轮播图或类似 ViewPager 的效果。

npx expo install react-native-pager-view

4. 本地存储:@react-native-async-storage/async-storage

轻量级、异步的键值对存储系统,类似于 Web 的 localStorage

npx expo install @react-native-async-storage/async-storage

提供 setItem, getItem, removeItem, clear, mergeItem 等异步方法。存储对象需先用 JSON.stringify() 序列化。

5. 地理位置:expo-location

获取设备的地理位置信息。需要在 app.json 中配置权限。

npx expo install expo-location

6. 相机:expo-camera

访问设备摄像头进行拍照或录像。需要在 app.json 中配置权限。

npx expo install expo-camera

7. 相册选择:expo-image-picker

从设备相册中选择图片或视频。需要在 app.json 中配置权限。

npx expo install expo-image-picker

四、状态管理:MobX

MobX 是一个简单、可扩展的状态管理库,适合中小型项目。

  1. 安装依赖:

    yarn add mobx mobx-react @babel/plugin-proposal-decorators
    
  2. Babel 配置 (babel.config.js):

    module.exports = {
      plugins: [["@babel/plugin-proposal-decorators", { "legacy": true }]]
    };
    
  3. 创建 Store:

    // mobx/index.js
    import { observable, action, makeObservable } from 'mobx';
    class RootStore {
      @observable name = '悟空';
      constructor() {
        makeObservable(this); // 高版本 MobX 必需
      }
      @action
      updateName(newName) {
        this.name = newName;
      }
    }
    export default new RootStore();
    
  4. 在组件中使用:

    • 根组件注入 Store:
      import { Provider } from 'mobx-react';
      import RootStore from './mobx';
      <Provider RootStore={RootStore}>...</Provider>
      
    • 子组件连接 Store (使用装饰器):
      import { inject, observer } from 'mobx-react';
      @inject('RootStore')
      @observer
      class MyComponent extends React.Component {
        render() {
          return <Text>{this.props.RootStore.name}</Text>;
        }
      }
      

五、导航:React Navigation

React Navigation 是 RN 社区主流的导航库,提供了栈、标签页、抽屉等多种导航模式。

  1. 安装核心依赖 (以 5.x 稳定版为例):

    yarn add @react-navigation/native@^5.x
    yarn add react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
    

    注意:在入口文件 (index.jsApp.js) 顶部引入 import 'react-native-gesture-handler';

  2. 栈导航 (Stack Navigator):

    yarn add @react-navigation/stack@^5.x
    
    import { createStackNavigator } from '@react-navigation/stack';
    const Stack = createStackNavigator();
    function App() {
      return (
        <NavigationContainer>
          <Stack.Navigator>
            <Stack.Screen name="Home" component={HomeScreen} options={{ title: '首页' }}/>
            <Stack.Screen name="Details" component={DetailsScreen} />
          </Stack.Navigator>
        </NavigationContainer>
      );
    }
    
  3. 底部标签导航 (Bottom Tab Navigator):

    yarn add @react-navigation/bottom-tabs@^5.x
    
  4. 抽屉导航 (Drawer Navigator):

    yarn add @react-navigation/drawer@^5.x
    
  5. 材料设计顶部标签导航 (Material Top Tab Navigator):

    yarn add @react-navigation/material-top-tabs react-native-tab-view@^2.x
    

导航器之间可以嵌套使用,并能通过 navigation.navigate('RouteName', { params }) 进行路由跳转和参数传递。

六、图标库:react-native-vector-icons

  1. 安装依赖:

    yarn add react-native-vector-icons
    
  2. Android 端配置 (对于裸 RN 项目): 需要将以下配置添加到 android/app/build.gradle 文件末尾:

    apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
    
  3. 使用:从库中导入具体的图标集(如 Ionicons, MaterialIcons),然后像普通组件一样使用。

    import Ionicons from 'react-native-vector-icons/Ionicons';
    <Ionicons name="ios-home" size={30} color="#4F8EF7" />
    

七、React Native 架构演进

  • 现有架构(传统架构):基于 JavaScript 线程与原生线程之间的“桥接”进行异步通信。这种模式在频繁通信时可能成为性能瓶颈。
  • 新架构(Fabric 与 TurboModules)
    • Fabric:新的渲染系统,允许 JavaScript 直接控制原生视图的创建与更新,同步渲染,减少丢帧。
    • TurboModules:新的原生模块系统,支持类型安全、同步调用和懒加载,提升启动速度和运行时性能。
    • Codegen:静态类型检查器,提升开发效率和新架构的兼容性。

新架构旨在提供更优的性能、更强的类型安全性和更好的互操作性,是 React Native 未来的发展方向。
yarn add @react-navigation/material-top-tabs@^5.x react-native-tab-view@^2.x

相比于TabView,Material Top Tabs 提供了滑动切换功能。以下是一个基本示例:

import * as React from "react"
import { Text, View } from "react-native"
import { NavigationContainer } from "@react-navigation/native"
import { createMaterialTopTabNavigator } from "@react-navigation/material-top-tabs"

function HomeScreen () {
    return (
        <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
            <Text>Home!</Text>
        </View>
    )
}

function SettingsScreen () {
    return (
        <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
            <Text>Settings!</Text>
        </View>
    )
}

const Tab = createMaterialTopTabNavigator()

export default function App () {
    return (
        <NavigationContainer>
            <Tab.Navigator>
                <Tab.Screen name="Home" component={HomeScreen} />
                <Tab.Screen name="Settings" component={SettingsScreen} />
            </Tab.Navigator>
        </NavigationContainer>
    )
}

注意,使用时可能因为 react-native-reanimated 报错,解决方法可参考 Installation | React Native Reanimated

6、路由嵌套

路由嵌套允许在导航器内部包含其他导航器。参考文档:https://reactnavigation.org/docs/5.x/nesting-navigators

以下是一个嵌套示例,在 Stack 导航器中包含一个 Bottom Tab 导航器:

import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"
import { Text, View } from "react-native"

function Feed(prop){
    return (
        <View>
            <Text>Feed</Text>
        </View>
    )
}

function Messages(prop){
    return (
        <View>
            <Text>Messages</Text>
        </View>
    )
}

function HomeScreen() {
    const Tab=createBottomTabNavigator()
    return (
        <Tab.Navigator>
            <Tab.Screen name="Feed" component={Feed} />
            <Tab.Screen name="Messages" component={Messages} />
        </Tab.Navigator>
    );
}

const Stack = createStackNavigator();

function App() {
    return (
        <NavigationContainer>
            <Stack.Navigator>
                <Stack.Screen name="Home" component={HomeScreen} />
            </Stack.Navigator>
        </NavigationContainer>
    );
}

export default App;

7、路由传参

在屏幕之间传递参数是常见的需求。参考文档:https://reactnavigation.org/docs/5.x/params

以下示例展示了如何传递和接收参数:

import * as React from 'react';
import { Button, Text, View } from "react-native"
import { NavigationContainer } from '@react-navigation/native'
import { createStackNavigator } from "@react-navigation/stack"

function HomeScreen({ navigation }) {
    return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
            <Text>Home Screen</Text>
            <Button
                title="Go to Details"
                onPress={() => {
                    navigation.navigate('Details', {
                        itemId: 86,
                        otherParam: 'anything you want here',
                    });
                }}
            />
        </View>
    );
}

function DetailsScreen({ route, navigation }) {
    const { itemId, otherParam } = route.params;
    return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
            <Text>Details Screen</Text>
            <Text>itemId: {JSON.stringify(itemId)}</Text>
            <Text>otherParam: {JSON.stringify(otherParam)}</Text>
            <Button
                title="Go to Details... again"
                onPress={() =>
                    navigation.push('Details', {
                        itemId: Math.floor(Math.random() * 100),
                    })
                }
            />
            <Button title="Go to Home" onPress={() => navigation.navigate('Home')} />
            <Button title="Go back" onPress={() => navigation.goBack()} />
        </View>
    );
}

const Stack = createStackNavigator();

export default function App() {
    return (
        <NavigationContainer>
            <Stack.Navigator>
                <Stack.Screen name="Home" component={HomeScreen} />
                <Stack.Screen name="Details" component={DetailsScreen} />
            </Stack.Navigator>
        </NavigationContainer>
    );
}

四、图标库的使用

React Native Vector Icons 是一个常用的图标库。仓库链接:GitHub - oblador/react-native-vector-icons

1、安装依赖

yarn add react-native-vector-icons

对于 Android 环境,需要额外配置。将以下代码添加到 android/app/build.gradle 文件末尾:

apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"

2、使用图标

可以选择 Ionicons 等图标集。引入依赖:

import Ionicons from 'react-native-vector-icons/Ionicons';

以下是在 Tab 导航中使用图标的案例:

import * as React from 'react';
import { Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import Ionicons from 'react-native-vector-icons/Ionicons';

function HomeScreen() {
    return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            <Text>Home!</Text>
        </View>
    );
}

function SettingsScreen() {
    return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            <Text>Settings!</Text>
        </View>
    );
}

const Tab = createBottomTabNavigator();

export default function App() {
    return (
        <NavigationContainer>
            <Tab.Navigator
                screenOptions={({ route }) => ({
                    tabBarIcon: ({ focused, color, size }) => {
                        let iconName;
                        if (route.name === 'Home') {
                            iconName = focused
                                ? 'ios-information-circle'
                                : 'ios-information-circle-outline';
                        } else if (route.name === 'Settings') {
                            iconName = focused ? 'ios-list-box' : 'ios-list';
                        }
                        return <Ionicons name={iconName} size={size} color={color} />;
                    },
                })}
                tabBarOptions={{
                    activeTintColor: 'tomato',
                    inactiveTintColor: 'gray',
                }}
            >
                <Tab.Screen name="Home" component={HomeScreen} />
                <Tab.Screen name="Settings" component={SettingsScreen} />
            </Tab.Navigator>
        </NavigationContainer>
    );
}

五、ReactNative架构

1、现有架构

React Native 的现有架构基于 Bridge 模式,允许 JavaScript 代码与原生模块通信。这种架构包括三个主要线程:JavaScript 线程、原生主线程和阴影线程。JavaScript 线程执行业务逻辑,原生线程处理 UI 渲染和原生功能,通过 Bridge 进行异步通信。

2、新架构

新架构旨在提高性能和开发体验,核心是 Fabric 渲染器和 TurboModules。Fabric 允许更高效的 UI 更新,直接同步到原生线程,减少通信开销。TurboModules 提供更强的类型安全和更快的模块加载。这些改进有助于提升应用响应速度和简化开发流程。

0 Answers