react native創(chuàng)建項目常用插件詳解
基本頁面路徑
my-app/ ├─ android/ # Android 原生代碼 ├─ ios/ # iOS 原生代碼 ├─ src/ # 主業(yè)務(wù)源碼 │ ├─ assets/ # 圖片、字體、icon、靜態(tài)資源 │ │ ├─ images/ │ │ ├─ fonts/ │ │ └─ icons/ │ ├─ components/ # 可復(fù)用組件(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/ # 全局狀態(tài)管理 │ │ ├─ index.ts # store 總?cè)肟? │ │ ├─ user.ts # 用戶狀態(tài) │ │ └─ home.ts # 首頁狀態(tài) │ ├─ services/ # 網(wǎng)絡(luò)請求 / API │ │ ├─ index.ts # axios / fetch 封裝 │ │ ├─ userApi.ts │ │ └─ productApi.ts │ ├─ hooks/ # 自定義 hooks │ │ ├─ useAuth.ts │ │ └─ useFetch.ts │ ├─ utils/ # 工具函數(shù) │ │ ├─ format.ts │ │ └─ storage.ts # MMKV/AsyncStorage 封裝 │ ├─ constants/ # 常量 │ │ ├─ colors.ts │ │ ├─ strings.ts │ │ └─ configs.ts │ └─ App.tsx # 應(yīng)用入口 ├─ index.js # RN入口文件 ├─ package.json ├─ tsconfig.json ├─ metro.config.js # RN打包配置 └─ babel.config.js
目錄設(shè)計原則
- 按功能模塊拆分
- pages → 按業(yè)務(wù)模塊(Home、User、Detail)
- components → 公共可復(fù)用組件(Button、Input、TabBar)
- 路由集中管理
- navigation 下統(tǒng)一管理 Stack + Tab,方便多人協(xié)作
- types.ts 用 TS 類型保證路由跳轉(zhuǎn)安全
- 狀態(tài)管理集中
- store 下按模塊拆分
- 每個模塊對應(yīng)自己的狀態(tài)文件,后期可擴(kuò)展為 Redux / Zustand / Jotai
- 服務(wù)層統(tǒng)一管理 API
- services 下按功能拆分
- 全局 axios / fetch 封裝,方便統(tǒng)一攔截請求、token刷新
- hooks + utils
- hooks → 自定義 hook(業(yè)務(wù)邏輯復(fù)用)
- utils → 工具函數(shù)(format、storage、debounce 等)
- assets 獨(dú)立靜態(tài)資源
- 圖片、字體、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
基礎(chǔ)配置 如tabbar頁面 子頁面
- 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>
);
}
- 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>
);
}
- 入口 — App.tsx
import { NavigationContainer } from "@react-navigation/native";
import StackNavigator from "./src/navigation/StackNavigator";
export default function App() {
return (
<NavigationContainer>
<StackNavigator/>
</NavigationContainer>
);
}
- 子頁面跳轉(zhuǎn)方式
import { useNavigation } from "@react-navigation/native";
export default function HomeScreen(){
const navigation = useNavigation();
return (
<Button
title="進(jìn)入詳情頁"
onPress={() => navigation.navigate("Detail",{ id:1001 })}
/>
);
}
<Button title=“Go to Detail” onPress={()=>navigation.navigate(‘Detail’,{id:“1545”})}/>類型報錯 類型“[string, { id: string; }]”的參數(shù)不能賦給類型“never”的參數(shù)
類型報錯解決方案
- 定義路由類型 types.ts
export type RootStackParamList = {
Tabs: undefined;
Detail: { id: string }; // ?? 這里定義參數(shù) id 為 string
};
- 修改 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>
);
}
- 頁面跳轉(zhuǎn)(你的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" })} // ? 現(xiàn)在不會報錯
/>
);
}
- 獲取參數(shù) 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
創(chuàng)建適配工具
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>
最后給你一句行業(yè)經(jīng)驗總結(jié)
- 組件寬高 = s() / vs()
- 字體 = ms()
- 全屏比例 = wp() / hp()
- 外加 SafeAreaView 適配劉海屏
舉例根據(jù)設(shè)計圖來實現(xiàn)適配方案
設(shè)計稿 & RN 換算規(guī)則
| 設(shè)計圖 750px | 手機(jī)實際寬度≈375dp | 換算比 = 375 / 750 = 0.5 |
|---|
所以換算邏輯
| 設(shè)計稿(px) | RN 等效尺寸(dp) |
|---|---|
| 300px | 150dp |
| 100px | 50dp |
| 文字 24px | 12dp |
| 設(shè)計稿值 | 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) }}>
商品標(biāo)題文字
</Text>
</View>
);
}
const styles = StyleSheet.create({
box: {
padding: s(30),
backgroundColor: "#fff",
}
});
記住一個黃金公式\
UI稿是多少px,RN就寫 s(x) / vs(x) / ms(px) 永遠(yuǎn)不用算 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',
},
},
],
],
};
如果不行 需要執(zhí)行 yarn start --reset-cache 重啟后再次啟動項目
RN中樣式 排列對齊方式
基本樣式寫法
- 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>
);
}
樣式屬性總結(jié)
- 布局相關(guān)
Flex 布局(RN 默認(rèn)是 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 |
- 背景相關(guān)
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>
- 文字相關(guān)
textStyle: {
fontSize: 24, // 字號
color: '#333', // 顏色
fontWeight: 'bold', // 加粗
fontStyle: 'italic',// 斜體
textAlign: 'center',// 水平對齊 left/center/right
lineHeight: 28, // 行高
}
- 邊距與內(nèi)邊距
box: {
margin: 10, // 外邊距
marginVertical: 5, // 上下外邊距
marginHorizontal: 10, // 左右外邊距
padding: 10, // 內(nèi)邊距
paddingHorizontal: 20,
paddingVertical: 15,
}
- 圓角、邊框、陰影
box: {
borderWidth: 1,
borderColor: '#ccc',
borderRadius: 8, // 圓角
shadowColor: '#000', // 陰影(iOS)
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.2,
shadowRadius: 4,
elevation: 5, // 陰影(Android)
}
- 寬高單位
- RN 不支持 px / rem,直接寫數(shù)字就是像素(密度獨(dú)立像素 dp)
- 可以結(jié)合 屏幕適配工具,比如 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 高度
},
});
常用技巧
- 組合樣式
<View style={[styles.box, { backgroundColor: 'red' }]}></View>
- 條件樣式
<Text style={[styles.text, isActive && styles.activeText]}></Text>
- 圖片背景用 ,文字可以疊加上去
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
使用React Profiler進(jìn)行性能優(yōu)化方案詳解
在現(xiàn)代前端開發(fā)中,性能優(yōu)化是一個不可忽視的重要環(huán)節(jié),在 React 生態(tài)系統(tǒng)中,React Profiler 是一個強(qiáng)大的工具,下面我們來看看如何使用它來提升我們的 React 應(yīng)用吧2025-03-03
React?Native實現(xiàn)Toast輕提示和loading效果
這篇文章主要介紹了React Native實現(xiàn)Toast輕提示和loading效果,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-09-09
使用react-activation實現(xiàn)keepAlive支持返回傳參
本文主要介紹了使用react-activation實現(xiàn)keepAlive支持返回傳參,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05
React構(gòu)建簡潔強(qiáng)大可擴(kuò)展的前端項目架構(gòu)
這篇文章主要為大家介紹了React構(gòu)建簡潔強(qiáng)大可擴(kuò)展的前端項目架構(gòu)實現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
ReactJs實現(xiàn)樹形結(jié)構(gòu)的數(shù)據(jù)顯示的組件的示例
本篇文章主要介紹了ReactJs實現(xiàn)樹形結(jié)構(gòu)的數(shù)據(jù)顯示的組件的示例,非常具有實用價值,需要的朋友可以參考下2017-08-08
React 模塊聯(lián)邦多模塊項目實戰(zhàn)詳解
這篇文章主要介紹了React 模塊聯(lián)邦多模塊項目實戰(zhàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10

