React Native 入门 jsx tsx 基础语法

React Native 入门 jsx 基础语法

JSX 介绍

JSX (JavaScript XML) 是一种 JavaScript 的语法扩展,允许你在 JavaScript 文件中编写类似 HTML 的代码。它是 React 和 React Native 应用程序中用来描述 UI 的主要方式。

image-20250428074413843

JSX 的特点

  • JSX 看起来像 HTML,但实际上是 JavaScript 的语法糖
  • JSX 让你可以在 JavaScript 代码中直接编写标签结构
  • JSX 通过转译器(如 Babel)被转换为纯 JavaScript 函数调用
  • JSX 使组件的结构和行为可以写在一起,提高代码的可读性和维护性

TSX 与 JSX 的区别

TSX 是 TypeScript 与 JSX 的结合:

  • TSX = TypeScript + JSX
  • .tsx 文件中,你可以使用 JSX 语法,同时享受 TypeScript 的类型检查
  • TypeScript 为 JSX 元素和组件提供了类型安全,帮助开发者在编译时发现潜在问题
  • TSX 文件中可以定义接口、类型和类型注解,增强代码的可维护性和可靠性

JSX 和 TSX 的工作原理

当你写下:

<View><Text>Hello, World!</Text>
</View>

它会被转译为:

React.createElement(View,null,React.createElement(Text, null, "Hello, World!")
);

TypeScript 会在这个过程中进行类型检查,确保你使用的组件和属性都符合预期的类型定义。

目录结构

img

├── android/                  # Android平台相关文件
│   ├── app/                  # Android应用特定配置
│   ├── build.gradle          # Android项目构建配置
│   ├── settings.gradle       # Android项目设置
│   ├── gradle.properties     # Gradle属性配置
│   ├── gradlew               # Gradle包装器脚本(Unix)
│   └── gradlew.bat           # Gradle包装器脚本(Windows)
│
├── ios/                      # iOS平台相关文件
│   ├── AwesomeProject1/      # iOS应用特定文件
│   ├── Podfile               # iOS依赖管理配置
│   └── AwesomeProject1.xcodeproj/ # Xcode项目文件
│
│
├── __tests__/                # 测试文件目录
│   └── App.test.tsx          # App组件的测试文件
│
├── node_modules/             # npm依赖包安装目录
│
├── App.tsx                   # 应用主要组件,定义UI和逻辑
├── index.js                  # 应用入口文件,注册应用组件
│
├── package.json              # 项目信息和npm依赖配置
├── package-lock.json         # npm依赖版本锁定文件
├── app.json                  # React Native应用配置
│
├── babel.config.js           # Babel转译器配置
├── metro.config.js           # Metro打包器配置
├── .eslintrc.js              # ESLint代码检查配置
├── .prettierrc.js            # Prettier代码格式化配置
├── .watchmanconfig           # Watchman文件监控配置
├── jest.config.js            # Jest测试框架配置
├── tsconfig.json             # TypeScript配置
│
├── Gemfile                   # Ruby gems依赖配置(iOS构建相关)
├── .bundle/                  # Ruby bundle安装目录
│
└── README.md                 # 项目说明文档

JSX 介绍

JSX and React 是相互独立的 东西。但它们经常一起使用,但你 可以 单独使用它们中的任意一个,JSX 是一种语法扩展,而 React 则是一个 JavaScript 的库。

JSX 是 JavaScript 语法扩展,可以让你在 JavaScript 文件中书写类似 H 标签。

javascript xml 在书写 js 的时候,直接写标签 把标签也看成 js 中的一种 类型

tsx typescript +xml

img

最简结构

import { Text, View } from "react-native";export default function App() {return (<View><Text>jsx语法</Text></View>);
}

img

JSX 规则

image-20250428074506209

只能返回一个根元素

import { Text, View } from "react-native";export default function App() {return (<View><Text>jsx语法</Text></View>);
}

如果你想要同时返回多个结构,可以使用 <></>语法把他们包裹起来

import React from "react";
import { Text } from "react-native";export default function App() {return (<><Text>jsx语法1</Text><Text>jsx语法2</Text></>);
}

标签必须闭合

不管单标签还是双标签都必须闭合

import { Button } from "react-native";export default function App() {return <Button title="点我" />;
}

使用驼峰式命名法给 大部分属性命名!

import { Alert, Button } from "react-native";export default function App() {return (<Buttontitle="点我"onPress={() => {Alert.alert("被征用");}}/>);
}

JSX 注释

{// 这里是单行注释
}
{/*这里是多行注释这里是多行注释这里是多行注释这里是多行注释*/
}

JSX 表达式

jsx 表达式可以让我在标签中嵌入表达式

import { Text, View } from "react-native";export default function App() {const msg = "我们的rn";const getNum = () => 100;return (<View>{/* 普通标签 */}<Text>普通标签</Text>{/* 数学运算 */}<Text>{1 + 1}</Text>{/* 字符串 */}<Text>{"a" + "b"}</Text>{/* 变量 */}<Text>{msg}</Text>{/* 三元表达式 */}<Text>{1 + 1 === 2 ? "对了" : "错误"}</Text>{/* 函数调用 */}<Text>{getNum()}</Text></View>);
}

属性上使用表达式

import { Button } from "react-native";export default function App() {const title = "登录";const showMsg = () => {};return <Button onPress={showMsg} title={title} />;
}

JSX 嵌套 JSX

可以把标签也看成是一种特殊的变量来理解以下代码

import { Text, View } from "react-native";export default function App() {return (<View style={{ padding: 10, backgroundColor: "yellow" }}>{<View style={{ padding: 10, backgroundColor: "blue" }}>{<Text style={{ padding: 10, backgroundColor: "orange" }}>哈哈</Text>}</View>}</View>);
}

img

JSX 条件渲染

image-20250428074542006

JSX 中实现条件渲染,可以三种方式

  1. 短路运算
  2. 三元表达式
  3. 如果是更加复杂的结构,函数中结合 if/else 来实现

短路运算

import { Button, View } from "react-native";export default function App() {return (<View><View>{true && <Button title="男" />}</View>;<View>{false && <Button title="女" />}</View>;</View>);
}

三元表达式

import { Button, View } from "react-native";export default function App() {return (<View><View>{true ? <Button title="男" /> : <Button title="女" />}</View>;</View>);
}

函数内 if/else

import { Button, View } from "react-native";export default function App() {const showBtn = () => {if (1 === 1) {return <Button title="111" />;} else {return <Button title="222" />;}};return (<View><View>{showBtn()}</View>;</View>);
}

jSX 列表渲染

image-20250428074711463

主要通过数组的 map 函数来实现

import { Button, View } from "react-native";export default function App() {const list = ["🍉", "🍎", "🍌", "🍇"];return (<View>{list.map((v, i) => (<Button title={v + i} key={v} />))}</View>);
}

样式

React Native 中,推荐组件和组件样式分离的写法 StyleSheet.create

import { Text, View, StyleSheet } from "react-native";export default function App() {return (<View style={styles.container}><Text>样式</Text></View>);
}const styles = StyleSheet.create({container: {backgroundColor: "blue",padding: 10,},
});

自定义组件 基本使用

后期可以根据需求,对组件进行导入、导出使用

import { Text, View } from "react-native";export default function App() {return (<View><Text>父组件</Text><Child /></View>);
}function Child() {return <Text>子组件</Text>;
}

useState

image-20250428074630970

useState 是 React 中用于更新状态的技术

useState 是一个函数,传入要设置的状态的初始值,返回一个数组,第一个元素是数据本身,第二个元素是修改元素的函数。

import { useState } from "react";
import { View, Button } from "react-native";export default function App() {const [num, setNum] = useState(0);return (<View><Buttontitle={num.toString()}onPress={() => {setNum(num + 1);}}/></View>);
}

需要注意的是,出于性能考虑,修改状态是异步的

import { useState } from "react";
import { View, Button, Alert } from "react-native";export default function App() {const [num, setNum] = useState(0);return (<View><Buttontitle={num.toString()}onPress={() => {setNum(10);Alert.alert("点击", num.toString()); // 输出0}}/></View>);
}

自定义组件 父子传参

image-20250428074740158

通过普通接口指定参数类型

import { Text, View } from "react-native";// 定义接口 - 更加清晰且可重用
interface ChildProps {color: string;
}export default function App() {let color = "red";return (<View><Text>父组件</Text><Child color={color} /></View>);
}function Child({ color }: ChildProps) {return <Text>子组件{color}</Text>;
}

通过 React.FC 指定参数类型

import React from "react";
import { Text, View } from "react-native";// 定义接口 - 更加清晰且可重用
interface ChildProps {color: string;
}export default function App() {let color = "red";return (<View><Text>父组件</Text><Child color={color} /></View>);
}// 使用React.FC<Props>类型,可以更明确地表明这是一个函数组件
const Child: React.FC<ChildProps> = ({ color }) => {return <Text>子组件{color}</Text>;
};

自定义组件 子父传参

import React, { useState } from "react";
import { View, Text, Button } from "react-native";// 定义子组件接收的props类型
interface CounterProps {value: number;onIncrement: () => void;
}// 父组件
export default function App() {// 在父组件中维护状态const [count, setCount] = useState(0);// 定义一个传递给子组件的函数const handleIncrement = () => {setCount(count + 1);};return (<View><Text>父组件</Text><Text>父组件中的计数: {count}</Text>{/* 向子组件传递属性和方法 */}<Counter value={count} onIncrement={handleIncrement} /></View>);
}
// 子组件
const Counter: React.FC<CounterProps> = ({ value, onIncrement }) => {return (<View><Text>子组件计数器: {value}</Text><Buttontitle="增加计数"onPress={() => {// 调用父组件传递的函数onIncrement();}}/></View>);
};

通过解构传递多个参数

import React, { useState } from "react";
import { View, Text, Button } from "react-native";// 定义子组件接收的props类型
interface ChildProps {name: string;age: number;score: number;hobbies: string[];onUpdateAge: () => void;onUpdateScore: (newScore: number) => void;
}// 父组件
export default function App() {// 在父组件中维护多个状态const [name] = useState("张三");const [age, setAge] = useState(25);const [score, setScore] = useState(85);const [hobbies] = useState(["阅读", "游泳", "编程"]);// 处理年龄更新const handleAgeUpdate = () => {setAge(age + 1);};// 处理分数更新const handleScoreUpdate = (newScore: number) => {setScore(newScore);};// 解构传递多个属性和方法const childProps = {name,age,score,hobbies,onUpdateAge: handleAgeUpdate,onUpdateScore: handleScoreUpdate,};return (<View><Text>父组件</Text><Text>姓名: {name}, 年龄: {age}, 分数: {score}</Text>{/* 方式1: 逐个传递属性 */}<Childname={name}age={age}score={score}hobbies={hobbies}onUpdateAge={handleAgeUpdate}onUpdateScore={handleScoreUpdate}/>{/* 方式2: 使用展开运算符传递所有属性 */}<Child {...childProps} /></View>);
}// 子组件 - 通过解构直接获取所需的属性
const Child: React.FC<ChildProps> = ({name,age,score,hobbies,onUpdateAge,onUpdateScore,
}) => {return (<View><Text>子组件</Text><Text>姓名: {name}</Text><Text>年龄: {age}</Text><Text>分数: {score}</Text><Text>爱好: {hobbies.join(", ")}</Text><Button title="增加年龄" onPress={onUpdateAge} /><Button title="提高分数" onPress={() => onUpdateScore(score + 5)} /></View>);
};

基础插槽

往自定义组件中插入我们想要的结构。它有以下常见的使用场景

  1. 卡片(Card)组件:包装内容并提供一致的外观
  2. 模态框(Modal):包装弹窗内容,但允许自定义内容
  3. 面板(Panel):带标题和可折叠功能的内容容器

img

import React from "react";
import { View, Text, Button } from "react-native";// 基础插槽:使用children
interface CardProps {title: string;children: React.ReactNode; // 定义children插槽
}// 基础插槽组件
const Card: React.FC<CardProps> = ({ title, children }) => {return (<View><Text>{title}</Text><View>{children}</View></View>);
};// 父组件
export default function App() {return (<View><Text>基础插槽示例</Text>{/* 基础插槽用法 */}<Card title="卡片标题"><Text>这是卡片内容</Text><Button title="卡片按钮" onPress={() => console.log("按钮点击")} /></Card></View>);
}

具名插槽

import React from "react";
import { View, Text, Button, StyleSheet } from "react-native";// 具名插槽:使用特定属性定义多个插槽
interface PanelProps {title: string;header?: React.ReactNode; // 可选的头部插槽content: React.ReactNode; // 主内容插槽footer?: React.ReactNode; // 可选的底部插槽
}// 具名插槽组件
const Panel: React.FC<PanelProps> = ({ title, header, content, footer }) => {return (<View style={styles.panel}><Text style={styles.panelTitle}>{title}</Text>{/* 头部插槽 */}{header && <View style={styles.panelHeader}>{header}</View>}{/* 内容插槽 */}<View style={styles.panelContent}>{content}</View>{/* 底部插槽 */}{footer && <View style={styles.panelFooter}>{footer}</View>}</View>);
};// 父组件
export default function App() {return (<View style={styles.container}><Text style={styles.header}>具名插槽示例</Text>{/* 具名插槽用法 */}<Paneltitle="具名插槽"header={<Text style={styles.headerText}>这是自定义头部区域</Text>}content={<View><Text>这是主要内容区域</Text><Buttontitle="内容区按钮"onPress={() => console.log("内容区按钮点击")}/></View>}footer={<View style={styles.footerButtons}><Button title="取消" onPress={() => console.log("取消")} /><Button title="确定" onPress={() => console.log("确定")} /></View>}/></View>);
}// 样式
const styles = StyleSheet.create({container: {padding: 16,gap: 16,},header: {fontSize: 20,fontWeight: "bold",marginBottom: 16,},panel: {backgroundColor: "#f9f9f9",borderRadius: 8,borderWidth: 1,borderColor: "#ddd",marginBottom: 16,overflow: "hidden",},panelTitle: {fontSize: 18,fontWeight: "bold",backgroundColor: "#eee",padding: 12,},panelHeader: {padding: 12,backgroundColor: "#f5f5f5",borderBottomWidth: 1,borderBottomColor: "#ddd",},headerText: {fontWeight: "600",},panelContent: {padding: 16,},panelFooter: {padding: 12,backgroundColor: "#f5f5f5",borderTopWidth: 1,borderTopColor: "#ddd",},footerButtons: {flexDirection: "row",justifyContent: "flex-end",gap: 8,},
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/78241.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HDLBIT-程序(Procedures)

始终块(组合)【Always blocks(combinational)】 答案: Always blocks (clocked) 答案&#xff1a; module top_module(input clk,input a,input b,output wire out_assign,output reg out_always_comb,output reg out_always_ff );assign out_assigna^b;always(*)beginout_a…

值此五一劳动节来临之际,

值此五一劳动节来临之际&#xff0c;谨向全体员工致以节日的问候与诚挚的感谢&#xff01;正是你们的敬业与奋斗&#xff0c;成就了今天的成绩。愿大家节日愉快&#xff0c;阖家幸福&#xff0c;身体健康&#xff01; #北京先智先行科技有限公司 #先知AI #节日快乐

【经管数据】A股上市公司资产定价效率数据(2000-2023年)

数据简介&#xff1a;资产定价效率是衡量市场是否能够有效、准确地反映资产内在价值的重要指标。在理想的市场条件下&#xff0c;资产的市场价格应该与其内在价值保持一致&#xff0c;即市场定价效率达到最高。然而&#xff0c;在实际市场中&#xff0c;由于信息不对称、交易摩…

云蝠智能大模型智能呼叫:赋能零售行业服务,助力客户增长

在数字化浪潮席卷全球的今天&#xff0c;零售行业正面临前所未有的变革压力。消费者需求日益个性化、市场竞争愈发激烈&#xff0c;传统的人工客服模式已难以满足企业对高效触达、精准营销和极致体验的需求。而云蝠智能大模型智能呼叫系统&#xff0c;凭借其突破性的AI技术和深…

IP 互联网协议

IP&#xff08;Internet Protocol&#xff0c;互联网协议&#xff09;是网络通信中的核心协议之一&#xff0c;属于网络层协议。它的主要功能是提供数据包的寻址、路由以及传输。IP协议负责将数据从源主机传输到目标主机&#xff0c;并在网络中进行转发。在网络通信中&#xff…

报文三次握手对么٩(๑^o^๑)۶

论TCP报文三次握手机制的理论完备性与工程实践价值&#xff1a;基于网络通信协议栈的深度剖析 在计算机网络领域&#xff0c;传输控制协议&#xff08;TCP&#xff09;作为实现可靠数据传输的核心协议&#xff0c;其连接建立阶段的三次握手机制历来是网络工程与协议理论研究的…

HarmonyOS NEXT第一课——HarmonyOS介绍

一、什么是HarmonyOS 万物互联时代应用开发的机遇、挑战和趋势 随着万物互联时代的开启&#xff0c;应用的设备底座将从几十亿手机扩展到数百亿IoT设备。全新的全场景设备体验&#xff0c;正深入改变消费者的使用习惯。 同时应用开发者也面临设备底座从手机单设备到全场景多设…

25.4.30数据结构|并查集 路径压缩

书接上回 上一节&#xff1a;数据结构|并查集 前言 &#xff08;一&#xff09;理论理解&#xff1a; 1、在QuickUnion快速合并的过程中&#xff0c;每次都要找根ID&#xff0c;而路径压缩让找根ID变得更加迅速直接。 2、路径压缩 针对的是findRootIndex()【查找根ID】进行的压…

C++-Lambda表达式

目录 1.什么是 Lambda&#xff1f; 2.例子&#xff1a;打印每个元素&#xff08;和 for_each 一起用&#xff09; 3.捕获外部变量&#xff08;Capture&#xff09; 3.1. 捕获值&#xff08;拷贝&#xff09;&#xff1a;[] 3.2. 捕获引用&#xff1a;[&] 3.3. 指定捕…

每日一题洛谷P8635 [蓝桥杯 2016 省 AB] 四平方和c++

P8635 [蓝桥杯 2016 省 AB] 四平方和 - 洛谷 (luogu.com.cn) 直接暴力枚举&#xff0c;不做任何优化的话最后会TLE一个&#xff0c;稍微优化一下就过了&#xff08;数据给的还是太良心了&#xff09; 优化&#xff1a;每层循环用if判断一下&#xff0c;如果大于n就直接跳 当然…

罗技K580蓝牙键盘连接mac pro

罗技K580蓝牙键盘&#xff0c;满足了我们的使用需求。最棒的是&#xff0c;它能够同时连接两个设备&#xff0c;通过按F11和F12键进行切换&#xff0c;简直不要太方便&#xff01; 连接电脑 &#x1f4bb; USB连接 1、打开键盘&#xff1a;双手按住凹槽两边向前推&#xff0…

C语言与指针3——基本数据类型

误区补充 char 的 表示范围0-127 signed char 127 unsigned char 0-255enum不常用&#xff0c;但是常见&#xff0c;这里记录一下。 enum Day {Monday 1,//范围是IntTuesday 2,Wednesday 3 }; enum Day d Monday; switch (d) {case Monday:{printf("%d",Monday);…

如何理解 MCP 和 A2A 的区别?|AI系统架构科普

你有没有发现,现在越来越多AI项目的架构图里,都开始出现一些看不懂的新缩写。 MCP(Multi-component Pipeline),还有另一个也经常出现在大模型系统搭建中的词,叫 A2A(Agent-to-Agent)。 这俩东西看起来都跟智能体(Agent)有关,但到底有啥区别?谁更强?谁更适合你?…

C语言中 typedef 关键字

在C语言中&#xff0c;typedef 关键字用于为现有数据类型定义新的别名&#xff08;类型重命名&#xff09;&#xff0c;其核心目的是‌提高代码可读性‌和‌简化复杂类型的声明‌。以下是其用法详解及典型场景&#xff1a; 1.基本语法‌ typedef original_type new_type_name…

Learning vtkjs之TubeFilter

过滤器 沿着线生成管道 介绍 vtkTubeFilter - 一个在每条输入线周围生成管的过滤器 vtkTubeFilter是一个在每条输入线周围生成管的过滤器。管由三角形条带组成&#xff0c;并随着线法线的旋转而旋转。如果没有法线存在&#xff0c;它们会自动计算。管的半径可以根据标量或向…

python常用科学计算库及使用示例

​一、NumPy - 数值计算基础库​​ ​​安装​​ pip install numpy ​​核心功能示例​​ 1. 数组创建与运算 import numpy as np# 创建数组 arr np.array([1, 2, 3, 4]) matrix np.array([[1, 2], [3, 4]])# 数学运算 print(arr 1) # [2 3 4 5] print(matrix …

中科院黄飞敏等人证明希尔伯特第六问题使用的或然判断(估计)-没有使用演绎推理的必然判断

国家自然科学基金委在2013年介绍黄飞敏的工作&#xff0c;居然是错误的&#xff1a;黄飞敏等人73页的论文&#xff0c;全篇都是用或然判断的“估计”代替必然判断的演绎证明&#xff0c;将没有实验的推演当成事实。 首页 >>年度报告 >>2013年度报告 >>第二部…

【安装指南】Chat2DB-集成了AI功能的数据库管理工具

一、Chat2DB 的介绍 Chat2DB 是一款开源的、AI 驱动的数据库工具和 SQL 客户端&#xff0c;提供现代化的图形界面&#xff0c;支持 MySQL、Oracle、PostgreSQL、DB2、SQL Server、SQLite、H2、ClickHouse、BigQuery 等多种数据库。它旨在简化数据库管理、SQL 查询编写、报表生…

vite项目tailwindcss4的使用

1、安装taillandcss 前几天接手了一个项目&#xff0c;看到别人用tailwindcss节省了很多css代码的编写&#xff0c;所以自己也想在公司项目中接入tailwindcss。 官网教程如下&#xff1a; Installing Tailwind CSS with Vite - Tailwind CSS 然而&#xff0c;我在vite中按…

第 13 届蓝桥杯 C++ 青少组省赛中 / 高级组 2022 年真题

一、选择题 第 1 题 题目&#xff1a;已知char a; float b; double c;&#xff0c;执行语句c a b c;后变量c的类型是&#xff08; &#xff09;。 A. char B. float C. double D. int 正确答案&#xff1a;C 答案解析&#xff1a; 在 C 中&#xff0c;表达式运算会进行类型…