学习 React【Plan - June - Week 1】

一、使用 JSX 书写标签语言

JSX 是一种 JavaScript 的语法扩展,React 使用它来描述用户界面。


什么是 JSX?

  • JSX 是 JavaScript 的一种语法扩展。
  • 看起来像 HTML,但它实际上是在 JavaScript 代码中写 XML/HTML。
  • 浏览器并不能直接运行 JSX,需要通过打包工具(如 Babel)将其转译为 JavaScript。

示例:

const element = <h1>Hello, world!</h1>;

1、JSX 的基本规则

使用大写字母定义组件

function MyButton() {return <button>I'm a button</button>;
}
  • 小写字母开头的标签,如 <div> 被解析为 HTML 标签。
  • 大写字母开头的标签,如 <MyButton> 被解析为 React 组件。

必须使用闭合标签

  • 所有标签必须闭合(类似 XML 语法)
// 正确
<input />
<br />
<MyComponent />// 错误
<input>

使用 {} 插入 JavaScript 表达式

const user = "小明";
const element = <h1>Hello, {user}!</h1>;
  • 只能插入表达式(不是语句)

合法表达式:

{1 + 2}
{user.name}
{formatDate(date)}

非法语句:

{if (isTrue) { ... }}
{for (...) { ... }}

使用 className 代替 class

// HTML 写法
<div class="container"></div>// JSX 写法
<div className="container"></div>

因为 class 是 JavaScript 的关键字,所以要使用 className


使用 camelCase 的属性名

// HTML 写法
<input tabindex="0" onclick="handleClick()" />// JSX 写法
<input tabIndex={0} onClick={handleClick} />

2、条件渲染和列表渲染

条件渲染

使用三元表达式、逻辑与 &&

{isLoggedIn ? <LogoutButton /> : <LoginButton />}{messages.length > 0 && <Notification messages={messages} />}

列表渲染

使用 map() 进行循环输出,并为每个子元素设置唯一的 key

const items = ['A', 'B', 'C'];<ul>{items.map(item => <li key={item}>{item}</li>)}
</ul>

3、JSX 转换成 JavaScript 的原理

JSX 会被转译为 React.createElement 调用:

const element = <h1 className="title">Hello</h1>;// 会被转换为:
const element = React.createElement('h1', { className: 'title' }, 'Hello');

4、组合 JSX

JSX 支持嵌套结构:

function App() {return (<div><Header /><Content /><Footer /></div>);
}

可使用片段(Fragment)避免多余的 DOM 元素:

<><td>内容1</td><td>内容2</td>
</>

5、JSX Tips

注释写法:

{/* 这是注释 */}

多行 JSX 需要用括号包裹:

return (<div><h1>Hello</h1></div>
);

二、组件(Component)

React 应用是由组件构成的,组件是可以复用的 UI 单元。


什么是组件?

  • 组件(Component) 是 React 的核心概念。
  • 本质上是一个返回 JSX 的函数。
  • 组件名称必须以大写字母开头。

示例:

function MyButton() {return <button>I'm a button</button>;
}

在 JSX 中使用:

export default function MyApp() {return (<div><h1>Welcome to my app</h1><MyButton /></div>);
}

组件命名规则

  • 必须以大写字母开头,否则会被当成 HTML 标签。
  • 使用 PascalCase 命名约定(每个单词首字母大写)。

1、组件是函数,不是标签

function MyButton() {return <button>Click me</button>;
}

这个 MyButton 是一个函数,而 <MyButton /> 是它的使用方式(调用)


2、组件可以复用

你可以多次使用同一个组件,它们是互相独立的:

function MyApp() {return (<div><MyButton /><MyButton /></div>);
}

每个 <MyButton /> 都会渲染一个独立的按钮。


3、组件的结构建议

建议为每个组件建一个文件(例如 MyButton.jsx),用于项目组织:

src/
├─ components/
│  └─ MyButton.jsx
└─ App.jsx

🧪 示例代码汇总

// MyButton.jsx
export default function MyButton() {return <button>I'm a button</button>;
}// App.jsx
import MyButton from './MyButton';export default function MyApp() {return (<div><h1>Welcome to my app</h1><MyButton /><MyButton /></div>);
}

三、State

React 的状态(state)允许组件“记住”信息。状态是让组件有“记忆”的机制,通常用于跟踪用户交互或界面变化。


1、什么是状态(State)?

  • 状态是组件的“记忆”
  • 在每次重新渲染时,组件的状态保持不变
  • 状态的变化会 触发组件的重新渲染

2、如何添加状态?

通过 useState Hook:

import { useState } from 'react';function MyComponent() {const [count, setCount] = useState(0);
}

useState 解释:

const [state, setState] = useState(initialValue);
名称含义
state当前状态值
setState用于更新状态的函数
initialValue初始状态值

3、状态的基本用法示例

import { useState } from 'react';export default function MyButton() {const [count, setCount] = useState(0);function handleClick() {setCount(count + 1);}return (<button onClick={handleClick}>Clicked {count} times</button>);
}

4、每次点击发生了什么?

  1. 点击按钮时,handleClick 被调用。
  2. setCount(count + 1) 更新状态。
  3. React 重新渲染组件。
  4. 新的 count 显示在界面上。

状态更新不会改变当前值,而是触发一次新的渲染,组件中的 count 会更新为新值。


5、状态在组件之间是隔离的

每个组件实例有自己独立的状态。

<MyButton />
<MyButton />

上面两个按钮互不影响,即使它们使用相同的 useState


6、不要直接修改 state 变量

// 错误写法(不会触发重新渲染)
count = count + 1;// 正确写法
setCount(count + 1);

只有通过 setCount 这样的更新函数,React 才会触发重新渲染。


7、多个状态变量

可以在一个组件中使用多个 useState

const [count, setCount] = useState(0);
const [name, setName] = useState('React');

8、示例完整代码

import { useState } from 'react';function MyButton() {const [count, setCount] = useState(0);function handleClick() {setCount(count + 1);}return (<button onClick={handleClick}>Clicked {count} times</button>);
}export default function MyApp() {return (<div><h1>Welcome to my app</h1><MyButton /><MyButton /></div>);
}

四、响应事件

React 使用类似 HTML 的方式来处理用户交互事件,比如点击、输入、悬停等。但语法略有不同,并支持更强的逻辑功能。


1、事件绑定基础

React 使用 onClickonChange 等属性来绑定事件处理函数。

示例:

function MyButton() {function handleClick() {alert('你点击了我!');}return (<button onClick={handleClick}>点击我</button>);
}

注意:

  • 使用驼峰命名(如 onClick,而不是 onclick
  • 事件处理函数是一个普通的 JavaScript 函数
  • JSX 中不使用字符串绑定函数(不同于 HTML 的 onclick="handleClick()"

2、为什么使用函数名而不是函数调用?

// 正确
onClick={handleClick}// 错误(会立即执行)
onClick={handleClick()}

你应传递函数的引用,而不是函数的执行结果。


3、使用箭头函数传参

有时你希望传递参数给事件处理函数,可以使用箭头函数:

function handleClick(name) {alert(`Hello, ${name}!`);
}<button onClick={() => handleClick('小明')}>Say Hello
</button>

4、在组件中组合事件处理逻辑

React 鼓励你将组件拆成小块,事件处理函数可以在组件内部定义或向下传递:

function Button({ onClick, children }) {return <button onClick={onClick}>{children}</button>;
}function App() {function handleClick() {alert('Clicked!');}return (<div><Button onClick={handleClick}>按钮1</Button><Button onClick={handleClick}>按钮2</Button></div>);
}

5、常见事件类型

React 事件名对应 HTML说明
onClickonclick点击事件
onChangeonchange输入/选择改变
onSubmitonsubmit表单提交
onMouseEnteronmouseenter鼠标进入
onKeyDownonkeydown按键按下

6、阻止默认行为

可以在事件中调用 event.preventDefault()

function handleSubmit(e) {e.preventDefault();alert('提交已阻止');
}<form onSubmit={handleSubmit}><button type="submit">提交</button>
</form>

7、React 与原生 DOM 事件的区别

项目React原生 HTML
命名方式驼峰命名,如 onClick小写,如 onclick
传递方式传函数引用传字符串或函数调用
自动阻止冒泡否,你仍需手动阻止冒泡同样需手动处理

8、示例完整代码

function Button({ message, children }) {function handleClick() {alert(message);}return (<button onClick={handleClick}>{children}</button>);
}export default function App() {return (<div><Button message="你好!">点我</Button><Button message="再见!">再点我</Button></div>);
}

五、React 哲学

“React 哲学” 教你如何从 UI 设计图开始,一步步将页面拆解为组件,再构建出数据驱动的交互式界面。


示例场景简介

我们要实现一个可搜索的商品表格(Searchable Product Table),它包含:

  • 一个搜索框
  • 一个是否只显示有库存商品的勾选框
  • 一个根据品类分组的商品表格

构建步骤总览

React 官方建议采用 五步法

  1. 将 UI 拆解为组件层级结构
  2. 构建组件的静态版本(无交互)
  3. 确定最小但完整的 UI 状态表示
  4. 确定哪些组件拥有状态(状态提升)
  5. 添加反向数据流(处理用户输入)

1、第一步:将 UI 拆解为组件层级

观察 UI,并根据界面结构拆出以下组件:

组件层级结构

FilterableProductTable (父组件)
├─ SearchBar
└─ ProductTable├─ ProductCategoryRow└─ ProductRow

每个组件的职责

组件名作用描述
FilterableProductTable管理所有状态,整合其他组件
SearchBar输入搜索文本与是否过滤库存
ProductTable接收数据与过滤条件,渲染表格
ProductCategoryRow显示每个品类的标题
ProductRow显示单个商品

2、第二步:构建静态版本(无交互)

  • 使用父组件 FilterableProductTable 将假数据通过 props 传给子组件。
  • 每个组件只关注如何显示数据,不包含状态或交互。
  • 假数据示例:
const PRODUCTS = [{category: "Fruits", price: "$1", stocked: true, name: "Apple"},{category: "Fruits", price: "$1", stocked: true, name: "Dragonfruit"},{category: "Fruits", price: "$2", stocked: false, name: "Passionfruit"},{category: "Vegetables", price: "$2", stocked: true, name: "Spinach"},{category: "Vegetables", price: "$4", stocked: false, name: "Pumpkin"},{category: "Vegetables", price: "$1", stocked: true, name: "Peas"}
];

3、第三步:确定最小但完整的 UI 状态(State)

根据界面交互功能,确定需要驱动 UI 的状态

  • 搜索文本(filterText
  • 是否只显示有库存商品(inStockOnly

不是状态的内容(可由 props 或其他状态推导得出):

  • 商品数据(是静态的)
  • 分类标题(可从数据中提取)
  • 筛选后的商品列表(由 filterText + inStockOnly 计算)

4、第四步:决定状态的归属

状态应该放在最“靠上的共同祖先组件”中。

状态名所属组件原因
filterTextFilterableProductTableSearchBar 和 ProductTable 都使用它
inStockOnlyFilterableProductTable同上

5、第五步:添加反向数据流(提升状态 + 子传父)

SearchBar 接收 filterTextinStockOnly 作为 props,并通过 onChange 回调将用户输入传递给父组件修改状态。

function SearchBar({ filterText, inStockOnly, onFilterTextChange, onInStockChange }) {return (<form><inputtype="text"value={filterText}onChange={(e) => onFilterTextChange(e.target.value)}placeholder="Search..."/><label><inputtype="checkbox"checked={inStockOnly}onChange={(e) => onInStockChange(e.target.checked)}/>Only show products in stock</label></form>);
}

6、组件结构(最终)

<FilterableProductTable products={PRODUCTS} />// 内部包含└── <SearchBarfilterText={...}inStockOnly={...}onFilterTextChange={...}onInStockChange={...}/>└── <ProductTableproducts={...}filterText={...}inStockOnly={...}/>

学习资料来源

使用 JSX 书写标签语言
第一个组件
State
响应事件
React 哲学

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

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

相关文章

小智AI+MCP

什么是小智AI和MCP 如果还不清楚的先看往期文章 手搓小智AI聊天机器人 MCP 深度解析&#xff1a;AI 的USB接口 如何使用小智MCP 1.刷支持mcp的小智固件 2.下载官方MCP的示例代码 Github&#xff1a;https://github.com/78/mcp-calculator 安这个步骤执行 其中MCP_ENDPOI…

基于python大数据的口红商品分析与推荐系统

博主介绍&#xff1a;高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了多年的设计程序开发&#xff0c;开发过上千套设计程序&#xff0c;没有什么华丽的语言&#xff0c;只有实实在…

ArcPy扩展模块的使用(3)

管理工程项目 arcpy.mp模块允许用户管理布局、地图、报表、文件夹连接、视图等工程项目。例如&#xff0c;可以更新、修复或替换图层数据源&#xff0c;修改图层的符号系统&#xff0c;甚至自动在线执行共享要托管在组织中的工程项。 以下代码展示了如何更新图层的数据源&…

打开GitHub网站因为网络原因导致加载失败问题解决方案

Date: 2025.06.09 20:34:22 author: lijianzhan 在Windows系统中&#xff0c;打开GitHub网站因为网络原因导致加载失败问题解决方案 打开Windows系统下方搜索框&#xff0c;搜索Microsoft Store&#xff0c;并且双击打开 在应用里面搜索Watt Toolkit&#xff0c;并下载安装 …

AI代码助手需求说明书架构

AI代码助手需求说明书架构 #mermaid-svg-6dtAzH7HjD5rehlu {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-6dtAzH7HjD5rehlu .error-icon{fill:#552222;}#mermaid-svg-6dtAzH7HjD5rehlu .error-text{fill:#552222;s…

.NET开发主流框架全方位对比分析

文章目录 1. ASP.NET Core核心特性代码示例&#xff1a;基本控制器优势劣势 2. .NET MAUI核心特性代码示例&#xff1a;基本页面优势劣势 3. Blazor两种托管模型核心特性代码示例&#xff1a;计数器组件优势劣势 4. WPF (Windows Presentation Foundation)核心特性代码示例&…

【系统架构设计师-2025上半年真题】案例分析-参考答案及部分详解(回忆版)

更多内容请见: 备考系统架构设计师-专栏介绍和目录 文章目录 试题一(25分)【问题1】(12分)【问题2】(13分)试题二(25分)【问题1】(10分)【问题2】(6分)【问题3】(9分)试题三(25分)【问题1】(13分)【问题2】(8分)【问题3】(4分)试题四(25分)【问题1】(6分)【问题2】(12…

【中间件】Web服务、消息队列、缓存与微服务治理:Nginx、Kafka、Redis、Nacos 详解

Nginx 是什么&#xff1a;高性能的HTTP和反向代理Web服务器。怎么用&#xff1a;通过配置文件定义代理规则、负载均衡、静态资源服务等。为什么用&#xff1a;提升Web服务性能、高并发处理、负载均衡和反向代理。优缺点&#xff1a;轻量高效&#xff0c;但动态处理能力较弱&am…

运动控制--小车的启动和停止算法

一、现实问题 小车在启动时由于受到惯性&#xff0c;后轮和前轮速度不一致&#xff0c;会引起车身不稳。 如小车上面装的是水&#xff0c;会出现倾洒&#xff0c;体验差。 二、数学研究 启动时 停止时 急动度&#xff08;jerk) 三、BLDC控制与S型曲线的融合逻…

WebFuture:Ubuntu 系统上在线安装.NET Core 8 的步骤

方法一&#xff1a;使用官方二进制包安装 下载.NET Core 8 SDK 二进制包&#xff1a;访问 .NET Core 8 SDK 官方下载页面&#xff0c;根据你的系统架构选择对应的 Linux x64 版本等下载链接&#xff0c;将其下载到本地4. 创建安装目录&#xff1a;在终端中执行以下命令创建用于…

可视化预警系统:如何实现生产风险的实时监控?

在生产环境中&#xff0c;风险无处不在&#xff0c;而传统的监控方式往往只能事后补救&#xff0c;难以做到提前预警。但如今&#xff0c;可视化预警系统正在改变这一切&#xff01;它能够实时收集和分析生产数据&#xff0c;通过直观的图表和警报&#xff0c;让管理者第一时间…

深度解析 Linux 内核参数 net.ipv4.tcp_rmem:优化网络性能的关键

文章目录 引言一、认识 net.ipv4.tcp_rmem1. 最小值&#xff08;min&#xff09;2. 默认值&#xff08;default&#xff09;3. 最大值&#xff08;max&#xff09; 二、net.ipv4.tcp_rmem 的工作原理三、net.ipv4.tcp_rmem 的实际应用场景1. 高并发 Web 服务器2. 文件传输服务3…

Windmill:开源开发者基础设施的革命者

前言 在企业内部,开发者经常需要构建各种内部工具来支持业务运营、数据分析和系统管理。这些工具通常需要前端界面、后端逻辑和工作流编排,开发过程繁琐且耗时。今天要介绍的Windmill项目,正是为解决这一痛点而生,它让构建内部工具变得简单高效,堪称开发者的得力助手。 …

国产化Excel处理组件Spire.XLS教程:用 Java 获取所有 Excel 工作表名称(图文详解)

在 Excel 中&#xff0c;工作表名称通常能够反映其用途或所含内容&#xff0c;提取这些名称有助于理清整个工作簿的结构。对于新用户或协作者来说&#xff0c;仅凭这些名称就能快速掌握各表中的数据类型。本文将演示如何使用 Java 获取 Excel 文件中的所有工作表名称&#xff0…

day49python打卡

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 最近临近毕业&#xff0c;事情有点多。如果有之前的基础的话&#xff0c;今天的难度相对较低。 后面说完几种模块提取特征的组合方式后&#xff0c;会提供整理的开源模块的文件。 现在大家已近可以去读这类…

day27-shell编程(自动化)

1. 准备工具 添加到/etc/vimrc autocmd BufNewFile *.py,*.cc,*.sh,*.java,*.bash,Dockerfile,docker-compose.yml exec ":call SetTitle()"func SetTitle() if expand("%:e") ~ sh\|bash call setline(1,"#!/bin/bash")call setline(2, &quo…

【免杀】C2免杀技术(十五)shellcode混淆uuid/ipv6/mac

针对 shellcode 混淆(Shellcode Obfuscation) 的实战手段还有很多,如下表所示: 类型举例目的编码 / 加密XOR、AES、RC4、Base64、Poly1305、UUID、IP/MAC改变字节特征,避开静态签名或 YARA结构伪装PE Stub、GIF/PNG 嵌入、RTF OLE、UUID、IP/MAC看起来像合法文件/数据,弱…

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…

记录一次opengl显示不出物体的错误原因

是这样的&#xff0c;我打算学PBR中的IBL章节&#xff0c;即基于图像的渲染&#xff0c;它的观点是创建一个大的外景图片&#xff0c;可以根据图像中的信息来将环境中的漫反射光和镜面反射光打在物体上。 但是我在我的程序中创建了一个立方体作为天空盒&#xff0c;我是有两套…

国产录播一体机:科技赋能智慧教育信息化

在数字化时代&#xff0c;教育正经历着前所未有的变革。国产工控机作为信息化教育的核心载体&#xff0c;正在重新定义学习方式&#xff0c;赋能教师与学生&#xff0c;打造高效、互动、智能的教学环境&#xff0c;让我们一起感受科技与教育的深度融合&#xff01;高能计算机推…