React Native 教程

什么是 React Native?

React Native 是 Facebook 开发的一个开源框架,用于使用 JavaScript 和 React 构建真正的原生移动应用。它允许开发者使用相同的代码库为 iOS 和 Android 平台开发应用。

核心特点

  1. 跨平台开发:一次编写,多平台运行(iOS 和 Android)
  2. 原生组件:使用真正的原生组件而非 WebView
  3. 热重载:快速刷新查看代码更改
  4. 社区支持:庞大的开发者社区和丰富的第三方库
  5. 性能接近原生:通过桥接技术与原生代码通信

与原生开发对比

特性 React Native 原生开发
语言 JavaScript Java/Kotlin (Android), Swift/Obj-C (iOS)
性能 接近原生 最佳
开发速度
代码复用 高 (跨平台)
UI 一致性 需要适配 原生体验
第三方库 JavaScript 生态 原生生态

与混合应用对比

React Native 不同于 Cordova/Ionic 等混合应用框架,它:

  • 不使用 WebView 渲染
  • 生成真正的原生视图
  • 性能更好
  • 用户体验更接近原生

二、环境搭建

1. 开发环境要求

macOS (iOS 和 Android 开发)

  • Node.js 12 LTS 或更高
  • Watchman (brew install watchman)
  • Xcode (iOS 开发)
  • Android Studio (Android 开发)
  • JDK 8 或更高

Windows (仅 Android 开发)

  • Node.js 12 LTS 或更高
  • Python 2
  • JDK 8 或更高
  • Android Studio

Linux (仅 Android 开发)

  • Node.js 12 LTS 或更高
  • Watchman (可选)
  • JDK 8 或更高
  • Android Studio

2. 安装 React Native CLI

npm install -g react-native-cli

3. 创建新项目

react-native init AwesomeProject
cd AwesomeProject

4. 运行项目

iOS

react-native run-ios
# 或使用 Xcode 打开 ios/AwesomeProject.xcodeproj

Android

react-native run-android
# 确保已启动 Android 模拟器或连接了设备

5. 项目目录结构

AwesomeProject/
  android/ - Android 原生代码
  ios/ - iOS 原生代码
  node_modules/ - 第三方依赖
  src/ - 通常用于存放应用代码 (可选)
  App.js - 主组件
  index.js - 入口文件
  package.json - 项目配置

三、基础组件

1. View

相当于 HTML 中的 <div>,是最基础的容器组件。

jsx

import { View } from 'react-native';

<View style={{ flex: 1, backgroundColor: 'white' }}>
  {/* 其他组件 */}
</View>

常用属性:

  • style: 应用样式
  • onLayout: 当组件挂载或布局变化时调用
  • pointerEvents: 控制视图是否可以成为触摸事件的目标

2. Text

用于显示文本的组件。

jsx

import { Text } from 'react-native';

<Text style={{ fontSize: 24 }}>Hello World!</Text>

常用属性:

  • style: 文本样式
  • numberOfLines: 限制行数
  • onPress: 点击事件
  • selectable: 是否可选

3. Image

用于显示图片的组件。

jsx

import { Image } from 'react-native';

// 网络图片
<Image 
  source={{ uri: 'https://example.com/image.jpg' }}
  style={{ width: 200, height: 200 }}
/>

// 本地图片
<Image 
  source={require('./local-image.png')}
  style={{ width: 200, height: 200 }}
/>

常用属性:

  • source: 图片源 (URI 或 require)
  • style: 图片样式
  • resizeMode: 调整大小模式 ('cover', 'contain', 'stretch' 等)
  • onLoad: 图片加载完成时调用

4. ScrollView

可滚动的容器组件。

jsx

import { ScrollView, Text } from 'react-native';

<ScrollView>
  {Array(20).fill().map((_, i) => (
    <Text key={i}>Item {i}</Text>
  ))}
</ScrollView>

常用属性:

  • horizontal: 水平滚动
  • showsHorizontalScrollIndicator: 显示水平滚动条
  • showsVerticalScrollIndicator: 显示垂直滚动条
  • refreshControl: 下拉刷新控件

5. TextInput

文本输入组件。

jsx

import { TextInput } from 'react-native';

<TextInput
  placeholder="Enter text"
  onChangeText={(text) => console.log(text)}
  value={this.state.text}
/>

常用属性:

  • value: 输入值
  • placeholder: 占位文本
  • onChangeText: 文本变化回调
  • keyboardType: 键盘类型 ('default', 'numeric', 'email-address' 等)
  • secureTextEntry: 密码输入

6. Button

基础按钮组件。

jsx

import { Button } from 'react-native';

<Button
  title="Press me"
  onPress={() => console.log('Pressed')}
/>

常用属性:

  • title: 按钮文本
  • onPress: 点击事件
  • color: 按钮颜色
  • disabled: 是否禁用

7. FlatList

高性能列表组件,适合长列表。

jsx

import { FlatList, Text } from 'react-native';

<FlatList
  data={[{key: 'a'}, {key: 'b'}]}
  renderItem={({item}) => <Text>{item.key}</Text>}
/>

常用属性:

  • data: 列表数据
  • renderItem: 渲染每个项目
  • keyExtractor: 提取唯一键
  • ListHeaderComponent: 头部组件
  • ListFooterComponent: 底部组件
  • onRefresh: 刷新回调
  • refreshing: 是否正在刷新

8. SectionList

带分区的列表组件。

jsx

import { SectionList, Text } from 'react-native';

<SectionList
  sections={[
    {title: 'A', data: ['Apple', 'Avocado']},
    {title: 'B', data: ['Banana', 'Blueberry']}
  ]}
  renderItem={({item}) => <Text>{item}</Text>}
  renderSectionHeader={({section}) => <Text>{section.title}</Text>}
/>

四、样式与布局

1. StyleSheet

React Native 使用 JavaScript 对象定义样式。

jsx

import { StyleSheet, View, Text } from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#fff'
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold'
  }
});

<View style={styles.container}>
  <Text style={styles.title}>Hello</Text>
</View>

样式继承

  • 大多数样式属性不会继承 (不同于 CSS)
  • 只有 Text 组件内的 Text 组件会继承部分文本样式

2. Flexbox 布局

React Native 使用 Flexbox 进行布局,类似于 CSS Flexbox 但有少许差异。

常用属性:

  • flex: 定义组件的伸缩能力
  • flexDirection: 主轴方向 ('row' 或 'column')
  • justifyContent: 主轴对齐方式
  • alignItems: 交叉轴对齐方式
  • alignSelf: 覆盖父组件的 alignItems
  • flexWrap: 是否换行

jsx

<View style={{
  flex: 1,
  flexDirection: 'row',
  justifyContent: 'space-around',
  alignItems: 'center'
}}>
  <View style={{width: 50, height: 50, backgroundColor: 'red'}} />
  <View style={{width: 50, height: 50, backgroundColor: 'green'}} />
  <View style={{width: 50, height: 50, backgroundColor: 'blue'}} />
</View>

3. 定位

  • position: 'relative'(默认) 或 'absolute'
  • top, right, bottom, left: 定位偏移量

jsx

<View style={{height: 100}}>
  <View style={{
    position: 'absolute',
    top: 10,
    right: 10,
    width: 50,
    height: 50,
    backgroundColor: 'red'
  }} />
</View>

4. 平台特定样式

jsx

import { Platform } from 'react-native';

const styles = StyleSheet.create({
  container: {
    height: Platform.OS === 'ios' ? 200 : 100,
    ...Platform.select({
      ios: {
        backgroundColor: 'red'
      },
      android: {
        backgroundColor: 'blue'
      }
    })
  }
});

五、导航

1. React Navigation

最流行的 React Native 导航库。

安装

npm install @react-navigation/native
npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

基本使用

jsx

import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();

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

2. 导航类型

堆栈导航 (Stack Navigation)

jsx

// 在屏幕组件中
navigation.navigate('Details', { itemId: 86 });
// 或
navigation.push('Details', { itemId: 86 }); // 允许重复

标签导航 (Tab Navigation)

jsx

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

const Tab = createBottomTabNavigator();

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

抽屉导航 (Drawer Navigation)

jsx

import { createDrawerNavigator } from '@react-navigation/drawer';

const Drawer = createDrawerNavigator();

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

六、状态管理

1. React 状态 (useState)

jsx

import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <View>
      <Text>You clicked {count} times</Text>
      <Button title="Click me" onPress={() => setCount(count + 1)} />
    </View>
  );
}

2. 上下文 API (useContext)

jsx

import React, { createContext, useContext } from 'react';

const ThemeContext = createContext('light');

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar() {
  const theme = useContext(ThemeContext);
  return <Text>Current theme: {theme}</Text>;
}

3. Redux

安装

npm install redux react-redux

基本使用

jsx

import { createStore } from 'redux';
import { Provider, useSelector, useDispatch } from 'react-redux';

// Reducer
function counter(state = 0, action) {
  switch (action.type) {
    case 'INCREMENT': return state + 1;
    case 'DECREMENT': return state - 1;
    default: return state;
  }
}

// Store
const store = createStore(counter);

function App() {
  return (
    <Provider store={store}>
      <Counter />
    </Provider>
  );
}

function Counter() {
  const count = useSelector(state => state);
  const dispatch = useDispatch();

  return (
    <View>
      <Text>{count}</Text>
      <Button title="+" onPress={() => dispatch({ type: 'INCREMENT' })} />
      <Button title="-" onPress={() => dispatch({ type: 'DECREMENT' })} />
    </View>
  );
}

七、网络请求

1. Fetch API

jsx

function App() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('https://api.example.com/items')
      .then(response => response.json())
      .then(json => setData(json))
      .catch(error => console.error(error));
  }, []);

  return (
    <View>
      {data ? <Text>{JSON.stringify(data)}</Text> : <Text>Loading...</Text>}
    </View>
  );
}

2. Axios

安装

npm install axios

使用

jsx

import axios from 'axios';

function App() {
  const [data, setData] = useState(null);

  useEffect(() => {
    axios.get('https://api.example.com/items')
      .then(response => setData(response.data))
      .catch(error => console.error(error));
  }, []);

  // 渲染...
}

八、原生功能集成

1. 访问设备功能

相机

npm install react-native-camera

地理位置

npm install react-native-geolocation-service

通知

npm install react-native-push-notification

2. 原生模块

创建原生模块允许你访问平台特定的 API。

Android 原生模块示例

// MyModule.java
public class MyModule extends ReactContextBaseJavaModule {
  MyModule(ReactApplicationContext context) {
    super(context);
  }

  @Override
  public String getName() {
    return "MyModule";
  }

  @ReactMethod
  public void show(String message, int duration) {
    Toast.makeText(getReactApplicationContext(), message, duration).show();
  }
}

iOS 原生模块示例

objc

// MyModule.m
#import <React/RCTBridgeModule.h>

@interface RCT_EXTERN_MODULE(MyModule, NSObject)

RCT_EXTERN_METHOD(show:(NSString *)message duration:(double)duration)

@end

JavaScript 中使用

jsx

import { NativeModules } from 'react-native';

NativeModules.MyModule.show('Hello', 5000);

九、调试与测试

1. 调试工具

React Developer Tools

npm install -g react-devtools
react-devtools

Flipper

  • 官方推荐的调试工具
  • 支持网络请求、日志、数据库等检查

2. 调试技巧

  • 摇动设备或按 Cmd+D (iOS) / Cmd+M (Android) 打开开发者菜单
  • 使用 console.log 输出日志
  • 使用 Chrome 开发者工具调试 JavaScript

3. 测试

Jest 测试

jsx

// sum.js
function sum(a, b) {
  return a + b;
}
module.exports = sum;

// sum.test.js
const sum = require('./sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

组件测试

npm install @testing-library/react-native

jsx

import { render, fireEvent } from '@testing-library/react-native';
import Button from '../Button';

test('button click', () => {
  const onPressMock = jest.fn();
  const { getByText } = render(<Button title="Press me" onPress={onPressMock} />);

  fireEvent.press(getByText('Press me'));
  expect(onPressMock).toHaveBeenCalled();
});

十、发布应用

1. Android 发布

生成签名密钥

keytool -genkeypair -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000

配置 gradle

编辑 android/app/build.gradle:

gradle

android {
    ...
    defaultConfig { ... }
    signingConfigs {
        release {
            storeFile file('my-release-key.keystore')
            storePassword 'your-password'
            keyAlias 'my-key-alias'
            keyPassword 'your-password'
        }
    }
    buildTypes {
        release {
            ...
            signingConfig signingConfigs.release
        }
    }
}

生成 APK

cd android && ./gradlew assembleRelease

2. iOS 发布

配置 Xcode

  1. 打开 Xcode 项目 (ios/YourProject.xcodeproj)
  2. 选择目标设备为 "Generic iOS Device"
  3. 选择 Product > Archive

App Store 发布

  1. 在 Xcode Organizer 中点击 "Distribute App"
  2. 选择 "App Store Connect"
  3. 按照向导完成上传

十一、性能优化

1. 常见性能问题

  • 不必要的重新渲染
  • 长列表性能问题
  • 动画卡顿
  • 内存泄漏

2. 优化技巧

使用 PureComponent 或 React.memo

jsx

const MyComponent = React.memo(function MyComponent(props) {
  /* 渲染使用 props */
});

优化 FlatList

jsx

<FlatList
  data={data}
  initialNumToRender={10} // 初始渲染数量
  windowSize={5} // 渲染窗口大小
  maxToRenderPerBatch={10} // 每批渲染数量
  updateCellsBatchingPeriod={50} // 批处理间隔
  keyExtractor={(item) => item.id}
  renderItem={({item}) => <ListItem item={item} />}
/>

使用 InteractionManager

jsx

InteractionManager.runAfterInteractions(() => {
  // 长时间任务
});

使用 Hermes 引擎 (Android)

编辑 android/app/build.gradle:

gradle

project.ext.react = [
    enableHermes: true
]

十二、常见问题与解决方案

1. 常见错误

"Unable to resolve module"

  • 确保已安装依赖 (npm install)
  • 尝试重置缓存 (npm start -- --reset-cache)

红屏错误

  • 仔细阅读错误信息
  • 检查组件是否正确导入
  • 检查 props 类型是否正确

2. 调试技巧

  • 使用 console.log 跟踪执行流程
  • 使用断点调试
  • 检查网络请求是否正确

3. 社区资源

结语

React Native 是一个强大的框架,可以让你使用 JavaScript 构建真正的原生移动应用。通过本教程,你已经学习了从环境搭建到应用发布的全过程,包括核心组件、样式、导航、状态管理、原生功能集成等关键概念。

要成为 React Native 专家,建议:

  1. 多实践,构建真实项目
  2. 阅读官方文档和源码
  3. 参与社区讨论
  4. 学习优秀的开源项目
  5. 关注 React Native 的最新发展

React Native 生态系统在不断进化,保持学习和实践是掌握它的关键。









results matching ""

    No results matching ""