当前位置: 首页 > news >正文

React Native基础

目录

一、创建项目

二、组件介绍

2.1、Text、View和Image组件

2.2、文件式导航(Link)

2.3、堆栈导航(Stack)

2.4、浅色与深色主题

2.5、主题化UI组件

2.6、路由分组与嵌套布局

2.7、Pressable组件

2.8、标签栏导航(Tabs)

2.9、安全区域适配(SafeAreaView)

一、创建项目

Expo官网:Expo Documentation (中文官网:教程:介绍 - Expo 中文网)

创建一个文件夹,在VS Code的终端下输入命令:

npx create-expo-app@latest --template blank ./创建出一个空白模板的app

在英文官网首页点击Set up your environment - Expo Documentation

设置路由:Install Expo Router - Expo Documentation

二、组件介绍

2.1、Text、View和Image组件

效果展示:

import { StyleSheet, Text, View, Image } from "react-native"; import Logo from "../assets/system.png"; export default function Page() { return ( <View style={styles.container}> {/* 文本 */} <Text style={styles.title}>The Number 1</Text> {/* 内联样式 */} <Text style={{ marginTop: 10 }}>Welcome to Expo</Text> {/* 外部样式+内联样式 */} <Text style={[styles.title,{color:'gold'}]}>Reading this app</Text> {/* 图片 */} <Image style={styles.img} source={Logo} /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "skyblue", alignItems: "center", justifyContent: "center", }, title: { fontSize: 20, fontWeight: "bold", }, img: { borderRadius: "50%", marginVertical: 10, }, });

2.2、文件式导航(Link)

import { Link } from "expo-router"; {/* 跳转 相当于HTML中的a标签 */} <Link href="/about">跳转到about页面</Link>

2.3、堆栈导航(Stack)

为了产生页面的返回键和页面标题,前提:在app文件夹下建立_layout.jsx文件。

import { Stack } from "expo-router"; const RootLayout = () => { return ( <Stack screenOptions={{ headerStyle: { backgroundColor: "#ddd" }, headerTintColor: "#333", }} > <Stack.Screen name="index" options={{title: "Home"}}/> <Stack.Screen name="about" options={{title: "About"}}/> <Stack.Screen name="contact" options={{title: "Contact"}}/> </Stack> ); }; export default RootLayout; // 如果第一步安装路由启动失败,加上_layout.jsx这个文件 // 可以重新安装依赖:rm -rf node_modules package-lock.json npm install // 想在web端查看页面:npx expo install react-dom react-native-web // 再重新运行:npx expo start

2.4、浅色与深色主题

import { useColorScheme } from "react-native"; import { Colors } from "../constants/Color"; import { StatusBar } from "expo-status-bar"; const RootLayout = () => { const colorScheme = useColorScheme(); const theme = Colors[colorScheme] ?? Colors.light; return ( <> <StatusBar value="auto" /> </> ); };

2.5、主题化UI组件

以View为例:

import { View, useColorScheme } from "react-native"; import {Colors} from "../constants/Color"; const ThemeView = ({ style, children, ...props }) => { const colorScheme = useColorScheme(); const theme = Colors[colorScheme] ?? Colors.light; return ( <View style={[style, { backgroundColor: theme.background }]} {...props}> {children} </View> ); }; export default ThemeView;

其实可以自己选组件库:

React Native ElementsReact Native PaperUI Kitten的文档如下(兼容IOS和安卓,后面两个可以搭配使用):

Overview | React Native Elements

ActivityIndicator | React Native Paper

UI Kitten - React Native Components

2.6、路由分组与嵌套布局

路由分组:将功能相关的路由归类,统一管理配置(如认证路由和主应用路由分离)

在app文件夹下再建一个文件夹,命名时用()括起来,此时页面title会变为"(auth/login)",此时想要取消页面的Header显示,则需要在(auth)文件夹下再建立一个_layout.jsx

import { Stack } from "expo-router"; import { StatusBar } from "expo-status-bar"; const AuthLayout = () => { return ( <> <StatusBar value="auto" /> <Stack screenOptions={{ headerShown: false, animation: "none", }} ></Stack> </> ); }; export default AuthLayout;

在RootLayout.jsx里

<Stack.Screen name="(auth)" options={{headerShown: false}}/>

或者使用createNativeStackNavigator分组

// App.js import { createNativeStackNavigator } from '@react-navigation/native-stack'; const AuthStack = createNativeStackNavigator(); const MainStack = createNativeStackNavigator(); function AuthGroup() { return ( <AuthStack.Navigator> <AuthStack.Screen name="Login" component={LoginScreen} /> <AuthStack.Screen name="Register" component={RegisterScreen} /> </AuthStack.Navigator> ); } function MainGroup() { return ( <MainStack.Navigator> <MainStack.Screen name="Home" component={HomeScreen} /> <MainStack.Screen name="Profile" component={ProfileScreen} /> </MainStack.Navigator> ); } // 根导航器整合分组 const RootStack = createNativeStackNavigator(); function App() { return ( <NavigationContainer> <RootStack.Navigator> <RootStack.Screen name="Auth" component={AuthGroup} options={{ headerShown: false }} /> <RootStack.Screen name="Main" component={MainGroup} options={{ headerShown: false }} /> </RootStack.Navigator> </NavigationContainer> ); }

拓展:

1. 路由参数传递

// 父路由传递参数给子路由 <Stack.Screen name="Profile" component={ProfileScreen} initialParams={{ userId: 123 }} /> // 子路由获取参数 function ProfileScreen({ route }) { const { userId } = route.params; }

2. 统一导航选项

// 分组统一配置 <Stack.Navigator screenOptions={{ headerStyle: { backgroundColor: '#4CAF50' }, headerTintColor: 'white' }} > {/* 所有子路由继承此样式 */} </Stack.Navigator>

3、动态隐藏Header:headerShown: false

2.7、Pressable组件

用于检测各种按压交互(点击、长按等)

自定义组件ThemeBtn.jsx:

import { StyleSheet, Pressable } from "react-native"; const ThemeBtn = ({ style, ...props }) => { return ( <Pressable style={({ pressed }) => [ styles.button, pressed && styles.buttonPressed, style, ]} {...props} /> ); }; export default ThemeBtn; const styles = StyleSheet.create({ button: { padding: 18, marginVertical: 10, borderRadius: 6, backgroundColor: "#6849a7", }, buttonPressed: { opacity: 0.5, }, });

父组件引用

import ThemeBtn from "../../components/ThemeBtn"; const Login = () => { const handleSubmit = () => { console.log("submit"); }; return ( <View> <ThemeBtn onPress={handleSubmit}> <Text style={{ color: "#f2f2f2", textAlign: "center" }}>Press Me</Text> </ThemeBtn> </View> ); }; export default Login;

列表项按压效果

function ListItem({ item }) { return ( <Pressable onPress={() => navigate('Detail', { id: item.id })} style={({ pressed }) => ({ padding: 16, backgroundColor: pressed ? '#f0f0f0' : 'white', })} > <Text>{item.name}</Text> </Pressable> ); }

2.8、标签栏导航(Tabs)

建立(dashboard)文件夹,分别建立三个.jsx文件:profile、books、create

import { Tabs } from "expo-router"; import { useColorScheme } from "react-native"; import { Colors } from "../../constants/Color"; // 下载图标 npm i @expo/vector-icons , 默认自带 import { Ionicons } from "@expo/vector-icons"; const DashboardLayout = () => { const colorScheme = useColorScheme(); const theme = colorScheme === "dark" ? Colors.dark : Colors.light; return ( <Tabs screenOptions={{ headerShown: false, tabBarStyle: { backgroundColor: theme.navBackground, paddingTop: theme.iconColor, height: 90, }, tabBarActiveTintColor: theme.iconColorFocused, tabBarInactiveTintColor: theme.iconColor, }} > {/* 自定义底部导航栏标题和图标 */} <Tabs.Screen name="profile" options={{ title: "Profile", tabBarIcon: ({ focused }) => ( <Ionicons name={focused ? "person" : "person-outline"} size={24} color={focused ? theme.iconColorFocused : theme.iconColor} /> ), }} /> <Tabs.Screen name="books" options={{ title: "Books" }} /> <Tabs.Screen name="create" options={{ title: "Create" }} /> </Tabs> ); }; export default DashboardLayout;

2.9、安全区域适配(SafeAreaView)

SafeAreaView:直接包裹当前页面,但是无法灵活控制具体哪一侧需要安全边距,所以选择以下HOOkuseSafeAreaInsets():可以手动获取安全区域的 top、bottom、left、right 值,并应用到样式中
import { View, useColorScheme } from "react-native"; import { Colors } from "../constants/Color"; import { useSafeAreaInsets } from "react-native-safe-area-context"; const ThemeView = ({ style, safe = false, ...props }) => { const colorScheme = useColorScheme(); const theme = Colors[colorScheme] ?? Colors.light; if (!safe) return ( <View style={[style, { backgroundColor: theme.background }]} {...props} /> ); const insets = useSafeAreaInsets(); return ( <View style={[ style, { backgroundColor: theme.background, paddingTop: insets.top, // 避开刘海 paddingBottom: insets.bottom, // 避开底部横条 }, ]} {...props} /> ); }; export default ThemeView;
http://www.jsqmd.com/news/894399/

相关文章:

  • React AJAX:深入浅出
  • JDK 下载安装成功后无法打开.jar文件
  • 解决Animagine XL 3.1常见问题:提升生成效果的实用解决方案
  • 表示秩分析:优化句子嵌入模型性能与稳定性的关键
  • UE4.26特效优化实战:用Cascade编辑器排查并解决粒子系统性能瓶颈
  • 鸣潮自动化工具终极指南:5个技巧解放你的游戏时间
  • 基于向量数据库与混合检索的AI智能体持久记忆系统构建
  • 从零组装一台CNC小机床:手把手教你用树莓派4B+DM542+步进电机搭建核心控制系统
  • vben中通过自定义指令 实现边界拖拽
  • 2026中水回用零排放设备企业精选:印染废水中水回用设备厂家盘点 - 栗子测评
  • 用STM32F407的SDIO给TF卡做个“体检”:读写速度测试与文件系统底层探索(FatFS预备篇)
  • AIFS Single v2.0 vs v1.1:6大核心升级让AI天气预报准确率提升30%
  • Atom-7B-Chat-openmind硬件兼容性指南:从NPU到消费级显卡的完整部署方案
  • 别再只跑官方Demo了!用Nerfstudio处理你自己的照片/视频,从数据准备到3D模型导出一站式指南
  • macOS窗口管理终极指南:AutoRaise提升多任务效率50%的完整教程
  • 如何永久保存你的微信聊天记录?免费开源工具WeChatMsg完整指南
  • 告别SDIO和USB!在i.MX8平台上为你的IoT设备选型与部署PCIe WIFI模块(以88W8997为例)
  • 无曝气PTFE-MBR+RO回用技术哪家好?2026优质合作厂商推荐 - 栗子测评
  • 从手势识别到UI交互:用LeapMotion在Unity里打造你的隔空操作Demo
  • Unity URP/HDRP项目里,用ShaderGraph节点快速实现5个酷炫效果(附节点图)
  • 别再只会用php://filter了!深入理解PHP文件包含的三种利用姿势:伪协议、远程包含与日志注入
  • Git常用命令教程,非常细致,零基础也能听懂
  • 城市规划师必备:如何用ArcGIS插件高效评估区域风环境(迎风面密度保姆级教程)
  • 2026采购指南:饮用水PFAS去除设备厂家汇总推荐 - 栗子测评
  • Qwen2.5-0.5B-Instruct模型下载与配置:从HuggingFace到本地部署完整教程
  • FactoryBluePrints:戴森球计划玩家的终极蓝图宝库,轻松建造宇宙工业帝国
  • 2026年靠谱的大连企业空气能供暖/空气能/大连空气能取暖销售设备供应商 - 品牌宣传支持者
  • 嵌入式工程师避坑指南:OV5640摄像头寄存器配置,这5个关键点新手最容易出错
  • 2026年4月有实力的吸塑托盘定制厂家怎么选择,胶盒吸塑/电子吸塑包装/五金吸塑包装/吸塑包装,吸塑托盘厂商哪家靠谱 - 品牌推荐师
  • 用Python和Keras从零搭建CNN:我的胃病影像识别课程设计复盘(附完整代码与数据集)