React Native快速指南

React Native快速指南

本文将从 React Native 的基础用法出发,介绍如何使用一套代码构建 iOS 与 Android 应用。内容涵盖项目创建、基础组件、页面布局、导航配置、状态管理、接口请求、调试方式以及原生能力调用,帮助前端开发者快速理解 React Native 的开发流程,并掌握移动端跨平台应用的基本实践。

核心组件

React Native UI 组件 Android 视图 iOS视图 网络模拟 描述
<View> <ViewGroup> <UIView> 无需滚动<div> 一个支持 Flexbox 布局、样式、部分触摸处理和辅助功能控制的容器
<Text> <TextView> <UITextView> <p> 显示、设置样式和嵌套文本字符串,甚至可以处理触摸事件
<Image> <ImageView> <UIImageView> <img> 显示不同类型的图像
<ScrollView> <ScrollView> <UIScrollView> <div> 一个通用的滚动容器,可以包含多个组件和视图
<TextInput> <EditText> <UITextField> <input type="text"> 允许用户输入文本

FlatList

与ScrollView区别:使用了虚拟列表,只渲染屏幕可见的元素

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;

平台相关代码

手动判断当前平台

import {Platform, StyleSheet} from 'react-native';

const styles = StyleSheet.create({
  height: Platform.OS === 'ios' ? 200 : 100,
});

自动选择平台

import {Platform, StyleSheet} from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    ...Platform.select({
      ios: {
        backgroundColor: 'red',
      },
      android: {
        backgroundColor: 'green',
      },
      default: {
        // other platforms, web for example
        backgroundColor: 'blue',
      },
    }),
  },
});

不同平台选择不同组件

const Component = Platform.select({
  ios: () => require('ComponentIOS'),
  android: () => require('ComponentAndroid'),
})();

<Component />;
const Component = Platform.select({
  native: () => require('ComponentForNative'),
  default: () => require('ComponentForWeb'),
})();

<Component />;

查看当前平台版本

Android:

import {Platform} from 'react-native';

if (Platform.Version === 25) {
  console.log('Running on Nougat!');
}

IOS:

import {Platform} from 'react-native';

const majorVersionIOS = parseInt(Platform.Version, 10);
if (majorVersionIOS <= 9) {
  console.log('Work around a change in behavior');
}

通过文件名区别平台

BigButton.ios.js
BigButton.android.js
import BigButton from './BigButton'; // 自动选择平台

样式

使用StyleSheet创建

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

const LotsOfStyles = () => {
  return (
    <View style={styles.container}>
      <Text style={styles.red}>just red</Text>
      <Text style={styles.bigBlue}>just bigBlue</Text>
      <Text style={[styles.bigBlue, styles.red]}>bigBlue, then red</Text>
      <Text style={[styles.red, styles.bigBlue]}>red, then bigBlue</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    marginTop: 50,
  },
  bigBlue: {
    color: 'blue',
    fontWeight: 'bold',
    fontSize: 30,
  },
  red: {
    color: 'red',
  },
});

export default LotsOfStyles;

Flex布局

与Web的区别:flexDirection在RN中默认为column ,而web是row

特性 React Native Web (CSS Flexbox)
默认主轴方向 column 纵向 📌 row 横向 📌
Flex 基准单位 直接表示权重(分配剩余空间) 表示增长倍数,受 flex-basis 影响
宽高计算方式 依赖父容器实际尺寸(必须有高度) 默认可以自适应内容大小
支持样式属性 Flex subset,少很多 Full CSS Flexbox spec
媒体查询等布局能力 ❌ 不支持 CSS ✔ 强大 CSS 特性
渲染引擎 Yoga 布局引擎 浏览器 CSS 引擎
文本布局 Text 是独立节点,需要不同布局规则 Inline text 默认布局

flex属性汇总

属性名 作用简述 可选值 / 类型 与 Web 的差异
display 启用 flex 布局 flex RN 默认就是 flex
flex 分配剩余空间的比例 number RN 更简单:不依赖 basis
flexGrow 可扩展比例 number 相同
flexShrink 缩小比例 number 相同
flexBasis 初始占用空间 number / string RN 少数支持百分比情况有限
flexDirection 主轴方向 row / column / row-reverse / column-reverse 默认 column(Web 默认 row)
flexWrap 是否换行 nowrap / wrap / wrap-reverse 行为不完全等同 Web
justifyContent 主轴对齐 flex-start / center / flex-end / space-between / space-around / space-evenly 相同
alignItems 交叉轴对齐 flex-start / center / flex-end / stretch / baseline baseline 支持较弱
alignSelf 单个子元素在交叉轴对齐 与 alignItems 同 相同
alignContent 多行对齐 与 justifyContent 同 多行场景有限
position 定位方式 relative / absolute 只有这两种
top / left / bottom / right 绝对定位偏移 number / % 与 Web 基本一致
rowGap / columnGap / gap 子元素间距 ❌不支持(除新版本部分实现) Web 支持较好

图片资源

<Image source={require('./my-icon.png')} />

Image 和 **ImageBackground**区别:

特性 Image ImageBackground
主要用途 显示一张图片 显示图片并作为背景容器
是否能放子元素 ❌ 不能 ✔ 可以放任意子组件
常用场景 图标、头像、封面图 背景图、Banner、带文本覆盖的图片
布局特性 作为“内容元素” 作为“布局容器”
API/Props 单一图片配置 Image 基础上增加 children 渲染功能

按钮

组件 自定义样式 点击视觉反馈 支持状态 平台 用法特点 / 场景
Button ❌ 很有限 ✔ 默认系统样式 只有 onPress iOS/Android 最简单快速的按钮,无需自定义样式;只适合纯按钮
TouchableOpacity ✔ 点击透明度变化 pressed / onPress / onLongPress iOS/Android 最常用,简单渐隐点击效果;可包裹任意元素
TouchableHighlight ✔ 背景高亮(变暗) pressed / onPress / onLongPress iOS/Android 点击时有高亮覆盖效果;列表或强调点击反馈常用
TouchableNativeFeedback ✔ 波纹效果 pressed / onPress / onLongPress Android 专属 安卓原生 Material 波纹效果,适合 Android 风格交互
TouchableWithoutFeedback ❌ 无视觉反馈 pressed / onPress / onLongPress iOS/Android 点击不显示任何反馈,适合自定义动画或处理复杂触控
Pressable ✔(动态样式) ✔ 可自定义 pressed / hover / focus / onPress / onLongPress / onPressIn / onPressOut iOS/Android/Web 统一替代 Touchable 系列,支持多状态,可根据状态动态样式,推荐新项目使用

动画

import React, {useEffect, useRef, type PropsWithChildren} from 'react';
import {Animated, Text, View, type ViewStyle} from 'react-native';

type FadeInViewProps = PropsWithChildren<{style: ViewStyle}>;

const FadeInView: React.FC<FadeInViewProps> = props => {
  const fadeAnim = useRef(new Animated.Value(0)).current; // Initial value for opacity: 0

  useEffect(() => {
    Animated.timing(fadeAnim, {
      toValue: 1,
      duration: 10000,
      useNativeDriver: true,
    }).start();
  }, [fadeAnim]);

  return (
    <Animated.View // Special animatable View
      style={{
        ...props.style,
        opacity: fadeAnim, // Bind opacity to animated value
      }}>
      {props.children}
    </Animated.View>
  );
};

// You can then use your `FadeInView` in place of a `View` in your components:
export default () => {
  return (
    <View
      style={{
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
      }}>
      <FadeInView
        style={{
          width: 250,
          height: 50,
          backgroundColor: 'powderblue',
        }}>
        <Text style={{fontSize: 28, textAlign: 'center', margin: 10}}>
          Fading in
        </Text>
      </FadeInView>
    </View>
  );
};

手势应答

回调函数 触发时机 返回值/作用 说明
onStartShouldSetResponder 手指按下 true/false 是否愿意成为 responder(接收触摸事件)
onMoveShouldSetResponder 手指移动 true/false 是否在手势移动时成为 responder
onResponderGrant 获得响应权 组件成为 responder 时触发(手势开始)
onResponderMove 手指移动 手势移动过程中持续触发
onResponderRelease 手指抬起 手势结束(释放)
onResponderTerminate 响应被抢占 另一个组件抢占 responder 权限时触发
onResponderTerminationRequest 响应抢占请求 true/false 是否允许被抢占,返回 true 则允许,返回 false 拒绝抢占
onStartShouldSetResponderCapture 手指按下(捕获阶段) true/false 捕获阶段判断是否想成为 responder(阻止子组件响应)
onMoveShouldSetResponderCapture 手指移动(捕获阶段) true/false 捕获阶段判断是否想成为 responder(阻止子组件响应)

evt是一个具有以下形式的合成触摸事件:

  • nativeEvent
    • changedTouches- 自上次事件以来所有已更改的触摸事件数组
    • identifier- 触摸的 ID
    • locationX- 触摸点相对于元素的 X 坐标
    • locationY- 触摸点相对于元素的 Y 坐标
    • pageX- 触摸点相对于根元素的 X 坐标
    • pageY- 触摸点相对于根元素的 Y 坐标
    • target- 接收到触摸事件的元素的节点 ID
    • timestamp- 用于记录触摸事件的时间标识符,可用于速度计算
    • touches- 屏幕上所有当前触摸点的数组
      <View
        style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}
        onStartShouldSetResponder={() => true} // 想成为 responder
        onResponderGrant={() => console.log('Gesture started')}
        onResponderMove={evt => console.log('Moving:', evt.nativeEvent)}
        onResponderRelease={() => console.log('Gesture ended')}
        onResponderReject={()=>{
          console.log("rejected");
        }}
      >
        <Text>Touch me!</Text>
      </View>