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

GJ504b 的 React 进阶之路:Day 4

目录
  • 📅 GJ504b 的 React 进阶之路:Day 4
    • 1 Button 与 Icon
    • 2 message(全局提示)
    • 3 Modal(对话框)
    • 4 Form 与 Input
    • 5 完整代码
    • 重温第二天力扣

📅 GJ504b 的 React 进阶之路:Day 4

今日立春
我们清空冗余缓存,期待 2026 的每一份装载
今天学习的 antd 的一些组件的使用方法

1 Button 与 Icon

按钮是触发交互的基础,通过属性配置可实现复杂的状态反馈。

技术要点

  • type="primary"danger:属性解耦,danger 可独立应用于任何类型的按钮。
  • icon={<IconName />}:将图标组件作为属性传入。
  • loading={bool}:绑定状态变量,实现异步处理时的视觉反馈与点击禁用。
  • htmlType="submit":在表单内部使用,用于关联表单的提交事件。

alt text
点击图标加载,3s 后恢复
alt text


<Buttontype='primary'{/* 1. danger是一个独立的属性 而不是在type里 */}dangericon={<SearchOutlined />}loading={loading}onClick={clickButton}
>加载中……
</Button>{/* 2. 绑定点击事件和loading状态 */}const [loading, setLoadings] = useState(false);const clickButton = () => {setLoadings(true);setTimeout(() => {setLoadings(false);}, 3000);// 3秒后loading状态变成false};

2 message(全局提示)

Ant Design 5.0 推荐使用 Hooks 方式调用,以保证样式的一致性和上下文的完整性。

技术要点

  • useMessage():解构出 messageApi(操作对象)和 contextHolder(渲染容器)。
  • {contextHolder}:必须写在 JSX 的根部,否则提示信息无法渲染。

alt text

const [messageApi, contextHolder] = message.useMessage(); //4. 引入message统一格式const clickButton = () => {setLoadings(true);setTimeout(() => {setLoadings(false);messageApi.info("搜索完成,找到0个相关患者"); //4. 引入message统一格式,info()方法,里面写要输出的内容}, 3000);
};// 渲染参考:
return (<Flex vertical>{contextHolder}{/* 4. 引入message统一格式,必须写 */}<Button onClick={clickButton}>触发提示</Button></Flex>
);

3 Modal(对话框)

Modal 不仅是容器,其在 HTML 结构中的位置直接影响系统的稳定性。

为什么 Modal 与 Button 必须是兄弟结构(平级)?

  1. HTML 容积限制<button> 是行内块级元素,无法合规承载 Modal 复杂的 div 嵌套结构。
  2. 冒泡效应(Event Bubbling):若嵌套,点击弹窗内的按钮会向上传递至父级按钮,引发逻辑死循环。
  3. Portal 传送门机制:Antd 底层会将 Modal 渲染至 <body> 根部,保持代码平级更符合实际渲染物理结构。

属性应用

  • footer={null}:移除默认的“确定/取消”按钮,由内部表单控制提交。

alt text
alt text


{/* 5. Modal与Button是同级的 */}
{/* 为什么不是父子结构:① HTML 的“肚量”有限
在网页的最底层,<button> 标签是一个行内块级元素,它只能装着文字、图标或者少量的修饰标签。Modal 的本质:它包含了遮罩层、标题、内容区、页脚按钮……这其实是一大堆嵌套的 <div>。后果:把一整栋楼(Modal)塞进一个信箱(Button)里,会导致浏览器解析出错,样式会变得乱七八糟。② “冒泡”效应 (Event Bubbling)
这是最麻烦的一点。在 JS 中,事件会向上冒泡:如果你把 Modal 放在 Button 里面,当你点击 Modal 里的“确定”按钮时,浏览器可能会认为你同时也点击了外层的 Button。死循环:这可能导致你刚想关掉弹窗,它又被外层的按钮触发重新打开了。③ 传送门逻辑 (Portals)
Ant Design 的 Modal 看起来是在你点击的地方弹出来的,但实际上为了不被父元素的样式(比如 overflow: hidden)遮挡,它在底层利用了 React 的 Portal(传送门) 技术,把自己偷偷渲染到了 HTML 的 <body> 最底部。所以,哪怕你在代码里把它写在按钮里,它最终也会“飞”到别的地方去。既然如此,为了代码整洁,我们干脆就让它们并列排放。 */}
<Button onClick={opening}>want to say sth to u</Button><Modal onCancel={isCancel} onOk={isOk} open={isOpen}>
{/* onCancel,onOk,open属性,当open属性true则显示,而button绑定切换open功能 */}
<p>Happy New Year!</p>
</Modal>const [isOpen, setIsOpen] = useState(false);
const opening = () => {
setIsOpen(true);
};
const isOk = () => {
setIsOpen(false);
};
const isCancel = () => {
setIsOpen(false);
};

4 Form 与 Input

表单是 B 端系统的灵魂,负责数据的采集、验证与上报。

技术要点

  • onFinish:提交触发的回调函数,其参数 value 是一个包含所有字段的对象。
  • Form.Itemname:定义数据键名。
  • rules:前端校验逻辑,required: true 实现非空约束。
  • 调试建议:使用 console.log("提示语", value) 而非模板字符串,以保留对象的交互检查特性。
    alt text
    alt text
    alt text
<Button type="primary" style={{width:'20%'}} onClick={formAdd}>添加姓名</Button>
<Modal open={form} footer={null}>
{/* footer={null}:去掉Modal默认的下部分(取消,ok) */}<h2>患者登记表</h2><Form layout="vertical" onFinish={onFinish} ><Form.Item label="姓名" name="username" rules={[{required:true,message:'请输入您的姓名'}]}><Input type="text" placeholder="请输入您的姓名" /></Form.Item><Form.Item ><Button type="primary" htmlType='submit'>立即登记</Button></Form.Item></Form>
</Modal>const onFinish = (value)=>{// console.log(`已经收到${value}`)// 打印一句话用 ${},检查一个对象用 逗号console.log("你拿到了数据",value)message.success(`成功录入:${value.username}`)setFrom(false)}const [form,setFrom] = useState(false)const formAdd =()=>{setFrom(true)}

5 完整代码

import React, { useState } from "react";
import { SearchOutlined } from "@ant-design/icons"; //引入icon库
import { Button, Flex, message, Modal,Form,Input } from "antd";
import useMessage from "antd/es/message/useMessage";
const App = () => {const [loading, setLoadings] = useState(false);const clickButton = () => {setLoadings(true);setTimeout(() => {setLoadings(false);messageApi.info("搜索完成,找到0个相关患者"); //4. 引入message统一格式,info()方法,里面写要输出的内容}, 3000);//2. 3秒后loading状态变成false};const [messageApi, contextHolder] = message.useMessage(); //4. 引入message统一格式const [isOpen, setIsOpen] = useState(false);const opening = () => {setIsOpen(true);};const isOk = () => {setIsOpen(false);};const isCancel = () => {setIsOpen(false);};const onFinish = (value)=>{// console.log(`已经收到${value}`)// 打印一句话用 ${},检查一个对象用 逗号console.log("你拿到了数据",value)message.success(`成功录入:${value.username}`)setFrom(false)}const [form,setFrom] = useState(false)const formAdd =()=>{setFrom(true)}return (<Flex gap='small' vertical>{contextHolder}{/* 4. 引入message统一格式,必须写 */}<Button type='primary' danger icon={<SearchOutlined />} loading>加载中……</Button>{/* 1. danger是一个独立的属性 而不是在type里 */}<Buttontype='primary'dangericon={<SearchOutlined />}loading={loading}onClick={clickButton}>加载中……</Button>{/* 3. 绑定点击事件和loading状态 */}{/* 5. Modal与Button是同级的 */}
{/* 为什么不是父子结构:① HTML 的“肚量”有限
在网页的最底层,<button> 标签是一个行内块级元素,它只能装着文字、图标或者少量的修饰标签。Modal 的本质:它包含了遮罩层、标题、内容区、页脚按钮……这其实是一大堆嵌套的 <div>。后果:把一整栋楼(Modal)塞进一个信箱(Button)里,会导致浏览器解析出错,样式会变得乱七八糟。② “冒泡”效应 (Event Bubbling)
这是最麻烦的一点。在 JS 中,事件会向上冒泡:如果你把 Modal 放在 Button 里面,当你点击 Modal 里的“确定”按钮时,浏览器可能会认为你同时也点击了外层的 Button。死循环:这可能导致你刚想关掉弹窗,它又被外层的按钮触发重新打开了。③ 传送门逻辑 (Portals)
Ant Design 的 Modal 看起来是在你点击的地方弹出来的,但实际上为了不被父元素的样式(比如 overflow: hidden)遮挡,它在底层利用了 React 的 Portal(传送门) 技术,把自己偷偷渲染到了 HTML 的 <body> 最底部。所以,哪怕你在代码里把它写在按钮里,它最终也会“飞”到别的地方去。既然如此,为了代码整洁,我们干脆就让它们并列排放。 */}<Button onClick={opening}>want to say sth to u</Button><Modal onCancel={isCancel} onOk={isOk} open={isOpen}>{/* onCancel,onOk,open属性,当open属性true则显示,而button绑定切换open功能 */}<p>Happy New Year!</p></Modal><Button type="primary" style={{width:'20%'}} onClick={formAdd}>添加姓名</Button><Modal open={form} footer={null}>{/* footer={null}:去掉Modal默认的下部分(取消,ok) */}<h2>患者登记表</h2><Form layout="vertical" onFinish={onFinish} ><Form.Item label="姓名" name="username" rules={[{required:true,message:'请输入您的姓名'}]}><Input type="text" placeholder="请输入您的姓名" /></Form.Item><Form.Item ><Button type="primary" htmlType='submit'>立即登记</Button></Form.Item></Form></Modal></Flex>);
};
export default App;

重温第二天力扣

做一半力扣在维修,只好明天了
alt text

/*** @param {string[]} strs* @return {string[][]}*/
var groupAnagrams = function (strs) {const map = new Map();for (let str of strs) {let arr = Array.from(str);// arr.sort((a, b) => a - b)//这里是字符排序,不可以,这个是数字排序//法1:直接sort(),Unicode就是字符排序// arr.sort()//法2:a.localeCompare(b) 是字符串的原生方法,专门用于字符串的字典序比较,返回值是数字(-1/0/1)arr.sort((a, b) => a.localeCompare(b));let key = arr.toString();let list = map.get(key) ? map.get(key) : new Array();list.push(str);map.set(key, list);}return Array.from(map.values());
};
http://www.jsqmd.com/news/343128/

相关文章:

  • 【无线传感器网络】多级动态优化智能LEACH与成本效益深度信念网络附Matlab代码
  • 任何东西都可以转成 Base64!?
  • spring6-注解式开发
  • CodeChef - TREEQUER
  • AI应用开发从入门到精通:打破“调接口”误区,收藏这一篇就够了!
  • 【无人机协同路径规划】基于六种最新优化算法(TOC、MSO、AE、DOA、GOA、OX)求解多个无人机协同路径规划研究(可以自定义无人机数量及起始点)附Matlab代码
  • 大模型Agent应用开发教程(非常详细),手把手教你从零构建智能体!
  • 从 synchronized 到 ConcurrentHashMap:一个小小的并发控制策略升级优化,证明我还是初级程序员
  • Claude Code生成UI的3个技巧
  • 【无人水面艇】USV路径跟踪LOS控制算法仿真附Matlab代码
  • Java面试早就不问八股文了!都是面试场景题,没做过根本回答不上来!
  • SQL性能优化秘籍:速度与简洁兼得
  • 汉中装修风格怎么选?汉府人家装饰本地业主实测好看风格盘点 - 一个呆呆
  • 大数据毕设项目推荐-基于Python+Echart的学生心理健康数据可视化系统设计与实现【附源码+文档,调试定制服务】
  • CSSCI期刊官宣:同一个作者一年内只能在核心期刊上发表一篇论文,你怎么看?
  • 大数据毕设选题推荐:Python大数据基于ECharts的数据分析可视化大屏基于Python+Echart的学生心理健康数据可视化系统设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 【无线传感器网络路由协议LEACH的研究与改进】LEACH、LEACH-C、TS-I-LEACH比较研究附Matlab代码
  • UOJ Round #33 部分题目题解
  • 中科院分区表发布在即!人工智能领域7本期刊升1区TOP,2025中科院分区升降对比!
  • 分布式锁的特性是什么?如何实现分布式锁?
  • 千兆宽带在英国城乡地区加速普及
  • 计算机大数据毕设实战-基于Python+Echart的学生心理健康数据可视化系统设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • Java 企业级 Agent 实战:完整工程模板 · 多 Agent + Graph 工作流落地指南
  • 老年人评估项目开发记录8
  • 5步搞定|宠物AI识别与智能剪辑开发实践
  • webvnc用法 —— 使用noVNC实现浏览器网页访问vnc(基于web的远程桌面)
  • 【毕业设计】基于Python+Echart的学生心理健康数据可视化系统设计与实现(源码+文档+远程调试,全bao定制等)
  • 408真题解析-2010-32-操作系统-中断处理过程
  • 2026年诚信的超高压水刀,五轴水刀厂家行业优选榜单 - 品牌鉴赏师
  • 道路直播:以安全为基,藏温暖于行