基本页面路径

my-app/
├─ android/                   # Android 原生代码
├─ ios/                       # iOS 原生代码
├─ src/                       # 主业务源码
│   ├─ assets/                # 图片、字体、icon、静态资源
│   │   ├─ images/
│   │   ├─ fonts/
│   │   └─ icons/
│   ├─ components/            # 可复用组件(UI组件)
│   │   ├─ Button/
│   │   ├─ Input/
│   │   └─ TabBar/
│   ├─ pages/                 # 页面(按模块拆分)
│   │   ├─ Home/
│   │   │   ├─ index.tsx
│   │   │   ├─ styles.ts
│   │   │   └─ components/    # 页面级私有组件
│   │   ├─ User/
│   │   └─ Detail/
│   ├─ router/            # 路由
│   │   ├─ RootNavigator.tsx  # Stack + Tab 主入口
│   │   ├─ TabNavigator.tsx   # TabBar 页面
│   │   └─ types.ts           # 路由类型 TS
│   ├─ store/                 # 全局状态管理
│   │   ├─ index.ts           # store 总入口
│   │   ├─ user.ts            # 用户状态
│   │   └─ home.ts            # 首页状态
│   ├─ services/              # 网络请求 / API
│   │   ├─ index.ts           # axios / fetch 封装
│   │   ├─ userApi.ts
│   │   └─ productApi.ts
│   ├─ hooks/                 # 自定义 hooks
│   │   ├─ useAuth.ts
│   │   └─ useFetch.ts
│   ├─ utils/                 # 工具函数
│   │   ├─ format.ts
│   │   └─ storage.ts         # MMKV/AsyncStorage 封装
│   ├─ constants/             # 常量
│   │   ├─ colors.ts
│   │   ├─ strings.ts
│   │   └─ configs.ts
│   └─ App.tsx                # 应用入口
├─ index.js                    # RN入口文件
├─ package.json
├─ tsconfig.json
├─ metro.config.js              # RN打包配置
└─ babel.config.js

目录设计原则

  1. 按功能模块拆分
  • pages → 按业务模块(Home、User、Detail)
  • components → 公共可复用组件(Button、Input、TabBar)
  1. 路由集中管理
  • navigation 下统一管理 Stack + Tab,方便多人协作
  • types.ts 用 TS 类型保证路由跳转安全
  1. 状态管理集中
  • store 下按模块拆分
  • 每个模块对应自己的状态文件,后期可扩展为 Redux / Zustand / Jotai
  1. 服务层统一管理 API
  • services 下按功能拆分
  • 全局 axios / fetch 封装,方便统一拦截请求、token刷新
  1. hooks + utils
  • hooks → 自定义 hook(业务逻辑复用)
  • utils → 工具函数(format、storage、debounce 等)
  1. assets 独立静态资源
  • 图片、字体、icon 分类,避免杂乱
  • 可配合 react-native-svg 或 @expo/vector-icons

路由常用插件

npm install @react-navigation/native @react-navigation/bottom-tabs @react-navigation/native-stack
npm install react-native-screens react-native-safe-area-context

基础配置 如tabbar页面 子页面

  1. src/navigation/TabNavigator.tsx 👉 4个TabBar
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import HomeScreen from "../screens/HomeScreen";
import CategoryScreen from "../screens/CategoryScreen";
import CartScreen from "../screens/CartScreen";
import ProfileScreen from "../screens/ProfileScreen";

const Tab = createBottomTabNavigator();

export default function TabNavigator() {
  return (
    <Tab.Navigator screenOptions={{ headerShown:false, tabBarActiveTintColor:"#0094FF" }}>
      <Tab.Screen name="Home" component={HomeScreen} options={{ title:"首页" }}/>
      <Tab.Screen name="Category" component={CategoryScreen} options={{ title:"分类" }}/>
      <Tab.Screen name="Cart" component={CartScreen} options={{ title:"购物车" }}/>
      <Tab.Screen name="Profile" component={ProfileScreen} options={{ title:"我的" }}/>
    </Tab.Navigator>
  );
}

  1. src/navigation/StackNavigator.tsx 👉 包含一个子页面
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import TabNavigator from "./TabNavigator";
import DetailScreen from "../screens/DetailScreen";

const Stack = createNativeStackNavigator();

export default function StackNavigator() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="Tabs" component={TabNavigator} options={{ headerShown:false }}/>
      <Stack.Screen name="Detail" component={DetailScreen} options={{ title:"商品详情" }}/>
    </Stack.Navigator>
  );
}

  1. 入口 — App.tsx
import { NavigationContainer } from "@react-navigation/native";
import StackNavigator from "./src/navigation/StackNavigator";

export default function App() {
  return (
    <NavigationContainer>
      <StackNavigator/>
    </NavigationContainer>
  );
}

  1. 子页面跳转方式
import { useNavigation } from "@react-navigation/native";

export default function HomeScreen(){
  const navigation = useNavigation();

  return (
    <Button 
      title="进入详情页"
      onPress={() => navigation.navigate("Detail",{ id:1001 })}
    />
  );
}

<Button title=“Go to Detail” onPress={()=>navigation.navigate(‘Detail’,{id:“1545”})}/>类型报错 类型“[string, { id: string; }]”的参数不能赋给类型“never”的参数

类型报错解决方案

  1. 定义路由类型 types.ts
export type RootStackParamList = {
  Tabs: undefined;
  Detail: { id: string };  // 🌟 这里定义参数 id 为 string
};

  1. 修改 StackNavigator.tsx 绑定类型
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { RootStackParamList } from "./types";
import TabNavigator from "./TabNavigator";
import DetailScreen from "../screens/DetailScreen";

const Stack = createNativeStackNavigator<RootStackParamList>(); // ★ 类型加上

export default function StackNavigator() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="Tabs" component={TabNavigator} options={{ headerShown: false }} />
      <Stack.Screen name="Detail" component={DetailScreen} />
    </Stack.Navigator>
  );
}

  1. 页面跳转(你的Button报错的地方)
import { useNavigation } from "@react-navigation/native";
import { NativeStackNavigationProp } from "@react-navigation/native-stack";
import { RootStackParamList } from "../navigation/types";

type Nav = NativeStackNavigationProp<RootStackParamList, 'Detail'>;

export default function HomeScreen() {
  const navigation = useNavigation<Nav>();

  return (
    <Button
      title="Go to Detail"
      onPress={() => navigation.navigate("Detail", { id: "1545" })} // ✔ 现在不会报错
    />
  );
}

  1. 获取参数 DetailScreen.tsx
import { RouteProp, useRoute } from "@react-navigation/native";
import { RootStackParamList } from "../navigation/types";

type DetailRoute = RouteProp<RootStackParamList, 'Detail'>;

export default function DetailScreen(){
  const { id } = useRoute<DetailRoute>().params;

  return <Text>商品ID: {id}</Text>;
}

页面适配方案

安装插件

npm i react-native-size-matters react-native-responsive-screen

创建适配工具

import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import { widthPercentageToDP, heightPercentageToDP } from "react-native-responsive-screen";

export const s = scale;         // 等比缩放 → UI宽度适配
export const vs = verticalScale; // 高度缩放
export const ms = moderateScale; // 缩放带衰减,字体更舒服

export const wp = widthPercentageToDP;   // 相对屏幕宽度百分比
export const hp = heightPercentageToDP;  // 相对屏高百分比

页面使用方法

import { View, Text, StyleSheet } from "react-native";
import { s, vs, ms, wp } from "../utils/scale";

export default function Demo() {
  return (
    <View style={{ padding: s(20) }}>
      <Text style={{ fontSize: ms(16) }}>适配字体</Text>
      <View style={{ width: wp(50), height: vs(120), backgroundColor: "skyblue" }} />
    </View>
  );
}

真实大厂适配方案组合建议

场景 推荐
页面布局、按钮宽高 s / vs 等比缩放
字体大小 ms()(更柔和,不会变大太夸张)
全屏组件 (Swiper / Banner) wp / hp
iOS 刘海屏适配 react-native-safe-area-context
npm i react-native-safe-area-context

import { SafeAreaView } from "react-native-safe-area-context";

<SafeAreaView style={{ flex:1 }}>
  <App/>
</SafeAreaView>

最后给你一句行业经验总结

组件宽高 = s() / vs()
字体 = ms()
全屏比例 = wp() / hp()
外加 SafeAreaView 适配刘海屏

举例根据设计图来实现适配方案

🎯 设计稿 & RN 换算规则

设计图 750px 手机实际宽度≈375dp 换算比 = 375 / 750 = 0.5

所以换算逻辑

设计稿(px) RN 等效尺寸(dp)
300px 150dp
100px 50dp
文字 24px 12dp
设计稿值 RN写法
宽300px → s(300)
高100px → vs(100)
文字24px → ms(24)
import { View, Text, Image, StyleSheet } from "react-native";
import { s, vs, ms } from "../utils/scale";

export default function Demo() {
  return (
    <View style={styles.box}>
      <Image 
        source={{ uri: "xxx.png" }} 
        style={{ width: s(300), height: vs(100), borderRadius: s(10) }} 
      />
      <Text style={{ fontSize: ms(24), marginTop: vs(20) }}>
        商品标题文字
      </Text>
    </View>
  );
}

const styles = StyleSheet.create({
  box: {
    padding: s(30),
    backgroundColor: "#fff",
  }
});

🏆 记住一个黄金公式\

UI稿是多少px,RN就写 s(x) / vs(x) / ms(px)
永远不用算 x/2 或 rem rpx 换算
屏幕再大也自动适配

路径别名

可以!React Native 项目完全可以像 Vue / UniApp一样使用 @/utils/scale 别名路径
不用再写 …/…/…/utils/scale 这种累死人写法。

npm i -D babel-plugin-module-resolver
yarn add -D metro-react-native-babel-preset

修改 babel.config.js
module.exports = {
  presets: ['module:@react-native/babel-preset'],
  plugins: [
    [
      'module-resolver',
      {
        root: ['./src'],
        extensions: ['.js', '.ts', '.tsx', '.json'],
        alias: {
          '@': './src',
          '@utils': './src/utils',
        },
      },
    ],
  ],
};




如果不行 需要执行 yarn start --reset-cache 重启后再次启动项目

RN中样式 排列对齐方式

基本样式写法

  1. RN 的样式主要通过 StyleSheet.create() 来写,也可以直接用对象:
import { StyleSheet, View, Text, Image } from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,                   // 占满父容器
    backgroundColor: '#f5f5f5', // 背景色
    alignItems: 'center',       // 水平居中
    justifyContent: 'center',   // 垂直居中
  },
  title: {
    fontSize: 24,               // 字体大小
    color: '#333',              // 文字颜色
    fontWeight: 'bold',         // 加粗
  },
  bgImage: {
    width: 300,
    height: 200,
    resizeMode: 'cover',        // 图片填充模式
  },
});

export default function App() {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>Hello React Native</Text>
      <Image
        style={styles.bgImage}
        source={{ uri: 'https://example.com/bg.png' }}
      />
    </View>
  );
}

样式属性总结

  1. 布局相关

Flex 布局(RN 默认是 flexDirection: ‘column’)

container: {
  flex: 1,
  flexDirection: 'row',      // row 水平排列,column 垂直排列
  justifyContent: 'center',  // 主轴对齐
  alignItems: 'center',      // 交叉轴对齐
}

属性 说明
flex 占用父容器比例
flexDirection 主轴方向,row / column
justifyContent 主轴对齐,flex-start / center / flex-end / space-between / space-around
alignItems 交叉轴对齐,flex-start / center / flex-end / stretch
  1. 背景相关
viewStyle: {
  backgroundColor: '#ff0000', // 背景色
}

  • RN 没有 background-image,背景图要用 或
import { ImageBackground } from 'react-native';

<ImageBackground
  style={{ width: '100%', height: 200 }}
  source={{ uri: 'https://example.com/bg.png' }}
>
  <Text>背景图上的文字</Text>
</ImageBackground>

  1. 文字相关
textStyle: {
  fontSize: 24,       // 字号
  color: '#333',      // 颜色
  fontWeight: 'bold', // 加粗
  fontStyle: 'italic',// 斜体
  textAlign: 'center',// 水平对齐 left/center/right
  lineHeight: 28,     // 行高
}

  1. 边距与内边距
box: {
  margin: 10,        // 外边距
  marginVertical: 5, // 上下外边距
  marginHorizontal: 10, // 左右外边距
  padding: 10,       // 内边距
  paddingHorizontal: 20,
  paddingVertical: 15,
}

  1. 圆角、边框、阴影
box: {
  borderWidth: 1,
  borderColor: '#ccc',
  borderRadius: 8, // 圆角
  shadowColor: '#000', // 阴影(iOS)
  shadowOffset: { width: 0, height: 2 },
  shadowOpacity: 0.2,
  shadowRadius: 4,
  elevation: 5, // 阴影(Android)
}

  1. 宽高单位
  • RN 不支持 px / rem,直接写数字就是像素(密度独立像素 dp)
  • 可以结合 屏幕适配工具,比如 react-native-size-matters 或自己封装 scale
import { s, vs, ms } from '@utils/scale';

const styles = StyleSheet.create({
  button: {
    width: s(300),   // scale 宽度
    height: vs(50),  // scale 高度
  },
});

常用技巧

  1. 组合样式
<View style={[styles.box, { backgroundColor: 'red' }]}></View>

  1. 条件样式
<Text style={[styles.text, isActive && styles.activeText]}></Text>

  1. 图片背景用 ,文字可以叠加上去

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐