React + 项目(从基础到实战) -- 第七期

使用ant design 表单组件,开发登录,注册,搜索功能

React 表单组件 ,受控组件

案列

使用defaultVlue属性

在这里插入图片描述

bug : 改变了数据源,但是页面未重新渲染

 {/* 表单组件 */}<button onClick={()=>{console.log(text);}}>打印</button><button onClick={()=>[setText("hello"),]}>set</button>

使用value

在这里插入图片描述


const [text , setText] = useState("hello world");const  handleChange=(e)=> {setText(e.target.value)}
--------------------------------------------<input value={text} onChange={handleChange}></input><button onClick={()=>{console.log(text);}}>打印</button><button onClick={()=>[setText("hello"),]}>set</button><button onClick={()=>[setText("hello"),]}>set</button>

总结

  1. 受控组件:
    值同步到state,使用value属性
  2. 非受控组件
    值不同步到state,使用default属性

常用表单组件

受控组件

import {FC} from "react";import { ChangeEvent, useState } from "react";const Demo : FC =()=>{const [text , setText] = useState<string>("hello world");const  handleChange=(e : ChangeEvent<HTMLInputElement>)=> {setText(e.target.value)}//---------------------------------------------------------------------const [tarea , setTarea] = useState<string>("hello");const handleChange2=(e : ChangeEvent<HTMLTextAreaElement>)=> {setTarea(e.target.value);}function getHtml() {return {__html: tarea.replaceAll("\n", "<br>")}}//-------------------------------------------------------------------------const [gender , setGender] = useState<string>("male");const handleGeander=(e : ChangeEvent<HTMLInputElement>)=> {setGender(e.target.value)}//-------------------------------------------------------------------------const[selectdIdList,setSelectdIdList]=useState<string[]>([]);const handleSelectd=(e : ChangeEvent<HTMLInputElement>)=> {const city = e.target.value;if(selectdIdList.includes(city)){//移除setSelectdIdList(selectdIdList.filter(item=>item!==city))}else{//添加setSelectdIdList(selectdIdList.concat(city))//   setSelectdIdList([...selectdIdList,city])}}//-------------------------------------------------------------------------const [lang , setLang] = useState<string>("1");const handleSelect=(e : ChangeEvent<HTMLSelectElement>)=> {setLang(e.target.value)}return (<div><h3>input 组件</h3><input value={text} onChange={handleChange}></input><button onClick={()=>{console.log(text);}}>打印</button><button onClick={()=>[setText("hello"),]}>set</button><h3>textarea 组件</h3><textarea value={tarea} onChange={handleChange2}></textarea>{/* {tarea}//没有换行 */}{/* {tarea.replaceAll("\n", "<br>")}//有xss注入的风险 */}<div dangerouslySetInnerHTML={getHtml()} />{/* 单选框 */}<h3>单选框  组件</h3>{/* 添加lable 实现点击文字也能选中效果 */}<label htmlFor="male">male</label><input type="radio" id="male" name="sex" value="male" checked={gender === "male"} onChange={handleGeander} /><label htmlFor="female">female</label><input type="radio" id="female" name="sex" value="female" checked={gender === "female"} onChange={handleGeander} />{/* 复选框 */}<h3>复选框  组件</h3><label htmlFor="1">shanghai</label><inputtype="checkbox"id="1"value="shanghai"checked={selectdIdList.includes("shanghai")}onChange={handleSelectd}/><label htmlFor="2">beijing</label><inputtype="checkbox"id="2"value="beijing"checked={selectdIdList.includes("beijing")}onChange={handleSelectd}/><label htmlFor="3">chengdu</label><inputtype="checkbox"id="3"value="chengdu"checked={selectdIdList.includes("chengdu")}onChange={handleSelectd}/>{JSON.stringify(selectdIdList)}{/* 下拉框 */}<h3>下拉框  组件</h3><select value={lang} onChange={handleSelect}><option value="1">1</option><option value="2">2</option><option value="3">3</option></select></div>)}export default  Demo;

form 组件

import {FC,useState,useRef, useEffect} from 'react'const Demo:FC =()=>{const handleSubmit = (e)=>{e.preventDefault();//阻止默认行为// js 提交数据console.log(e.target.k1.value);console.log(e.target.k2.value);}return(<><h3>Form 组件</h3>{/* 点击提交会触发请求,请求的地址是:https://www.baidu.com?k1=k1&k2=k2 \提交的参数{k1:v1;k2:v2;}*/}<form action="https://www.baidu.com" method="get"><input name='k1' value='k1'/><br /><br /><input name='k2' value='k2' /><br /><br /><input type="submit" value="提交" /></form>{/* 添加onsubmit,阻止默认行为 */}<form action="https://www.baidu.com" method="get" onSubmit={handleSubmit}><input name='k1' value='k1'/><br /><br /><input name='k2' value='k2' /><br /><br /><input type="submit" value="提交" /></form></>)}export default Demo;

ant design 表单组件

封装LisSearch组件

import {FC , useState ,useEffect} from 'react'import { useNavigate , useLocation ,useSearchParams} from 'react-router-dom';import { Input } from "antd";//引入常量import {LIST_SEARCH_PARAM_KEY} from '../constant/index.js';const {Search} = Input;  const ListSearch: FC = () => {//路由跳转const nav = useNavigate();//获取urlconst {pathname} = useLocation();//获取url参数,设置到搜索框中const [searchParams] = useSearchParams();useEffect(()=>{const searchVal = searchParams.get(LIST_SEARCH_PARAM_KEY) || "";//设置搜索框的值setVal(searchVal)},[searchParams])const handleSearch =(val : string )=>{//搜索时改变url,防止刷新丢失信息//跳转页面,增加url参数nav({pathname: pathname,search: `${LIST_SEARCH_PARAM_KEY}=${val}`})}//受控组件const [val, setVal] = useState<string>('');const handleChange =(e : React.ChangeEvent<HTMLInputElement>)=>{setVal(e.target.value)}return(<div><Search value={val} onChange={handleChange} placeholder="请输入关键字" style={{ width: 200 }} onSearch={handleSearch} /></div>)}export default ListSearch;

表单组件的校验

ant design rules

校验之前

const Register : FC = ()=>{const onfinish = (values) => {console.log('Received values of form: ', values);}return (<><div className={styles.container}><div><Space><Title level={2}><UserAddOutlined />    </Title><Title level={2}>注册新用户</Title></Space></div><div><Formname="basic"labelCol={{ span: 6 }}wrapperCol={{ span: 16 }}initialValues={{ remember: true }}autoComplete="off"onFinish={onfinish}><Form.Itemlabel="用户名"name="username"><Input /></Form.Item><Form.Itemlabel="密码"name="password"><Input.Password /></Form.Item><Form.Itemlabel="确认秘密"name="checkedPassword"><Input.Password /></Form.Item><Form.Itemlabel="昵称"name="nickname"><Input /></Form.Item><Form.Item wrapperCol={{ offset: 6, span: 16 }}><Space><Button type="primary" size='small' htmlType="submit">注册</Button><Link to={LOGIN_PATH}>已有账户, 登录</Link></Space></Form.Item></Form></div></div></>)}

校验之后

const Register : FC = ()=>{const onfinish = (values) => {console.log('Received values of form: ', values);}return (<><div className={styles.container}><div><Space><Title level={2}><UserAddOutlined />    </Title><Title level={2}>注册新用户</Title></Space></div><div><Formname="basic"labelCol={{ span: 6 }}wrapperCol={{ span: 16 }}initialValues={{ remember: true }}autoComplete="off"onFinish={onfinish}><Form.Itemlabel="用户名"name="username"rules={[{required:true , message:'请输入用户名'},{type: 'string', min : 5, max: 20 , message:'用户名长度为5-20'},{pattern : /^[a-zA-Z0-9_]+$/ , message:'用户名只能包含字母、数字、下划线'}]}><Input /></Form.Item><Form.Itemlabel="密码"name="password"rules={[{required:true , message:'请输入密码'},]}><Input.Password /></Form.Item><Form.Itemlabel="确认秘密"name="confirm"dependencies={["password"]}// 依赖项,password 变化时触发validateFieldrules={[{required:true , message:'请确认密码'},({getFieldValue}) => ({validator(_,val){if(!val || getFieldValue("password") === val){return Promise.resolve()}else{return Promise.reject(new Error('两次输入的密码不一致'))}}})]}><Input.Password /></Form.Item><Form.Itemlabel="昵称"name="nickname"><Input /></Form.Item><Form.Item wrapperCol={{ offset: 6, span: 16 }}><Space><Button type="primary" size='small' htmlType="submit">注册</Button><Link to={LOGIN_PATH}>已有账户, 登录</Link></Space></Form.Item></Form></div></div></>)}

第三方表单校验工具

react -hook-form

React Hook Form - performant, flexible and extensible form library (react-hook-form.com)

formik

Formik: Build forms in React, without the tears

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

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

相关文章

【InternLM 实战营第二期笔记01】书生·浦语大模型全链路开源体系+InternLM2技术报告

本次课程链接在GitHub上&#xff1a;InternLM/Tutorial at camp2 (github.com) 第一次课程录播链接&#xff1a;书生浦语大模型全链路开源体系_哔哩哔哩_bilibili InternLM2技术报告&#xff1a;arxiv.org/pdf/2403.17297.pdf 一、书生浦语大模型全链路开源体系笔记 Intern…

【读书笔记】自动驾驶与机器人中的SLAM技术——高翔

文章会对本书第五章节及以后章节进行总结概括。每日更新一部分。一起读书吧。 第五章——基础点云处理 重点&#xff1a;点云的相邻关系是许多算法的基础 5.1 激光雷达传感器与点云的数学模型 5.1.1激光雷达传感器的数学模型 雷达有两种&#xff1a;机械旋转式激光雷达&…

python 海龟画图tutle螺旋线

目录 初识turtle模块 基本绘图概念 示例&#xff1a;绘制一个正方形 示例&#xff1a;绘制彩色螺旋线 附录 常用命令 其它命令 在Python编程中&#xff0c;使用turtle模块进行图形绘制是一种非常有趣和富有教育意义的活动。通过控制一个小海龟&#xff08;Turtle&#x…

【产品经理修炼之道】- 厂商银业务之保兑仓

保兑仓 保兑仓是指供应商、购货商、银行签订三方协议&#xff0c;以银行信用为载体&#xff0c;以银行承兑汇票为结算工具&#xff0c;由银行控制货权&#xff0c;供应商受托保管货物并对银行承兑汇票保证金以外部分以货物回购为担保措施&#xff0c;购货商随缴保证金随提货而设…

《QT实用小工具·二十六》运行时间记录

1、概述 源码放在文章末尾 运行时间记录&#xff0c;包含如下功能&#xff1a; 可以启动和停止服务&#xff0c;在需要的时候启动。 可以指定日志文件存放目录。 可以指定时间日志输出间隔。 可以单独追加一条记录到日志文件。 日志为文本格式&#xff0c;清晰明了。 软…

AAAI24 - Model Reuse Tutorial

前言 如果你对这篇文章感兴趣&#xff0c;可以点击「【访客必读 - 指引页】一文囊括主页内所有高质量博客」&#xff0c;查看完整博客分类与对应链接。 该篇 Tutorial 主要对 Model Reuse 当下的进展进行了整理和总结。 The Paradigm Shifts Tutorial 中指出在一些数据量比较…

STM32学习和实践笔记(12):蜂鸣器实验

蜂鸣器主要分为两种&#xff0c;一种是压电式的无源蜂鸣器&#xff0c;一种是电磁式的有源蜂鸣器。 有源和无源是指其内部有没有振荡器。 无源的没有内部振荡器&#xff0c;需要输入1.5-5KHZ的音频信号来驱动压电蜂鸣片发声。 有源的内部有振荡器&#xff0c;因此只需要供给…

PostgreSQL入门到实战-第二十七弹

PostgreSQL入门到实战 PostgreSQL中数据分组操作(二)官网地址PostgreSQL概述PostgreSQL中HAVING命令理论PostgreSQL中HAVING命令实战更新计划 PostgreSQL中数据分组操作(二) 使用PostgreSQL HAVING子句来指定组或聚合的搜索条件 官网地址 声明: 由于操作系统, 版本更新等原因…

基于Python豆瓣电影数据可视化分析系统的设计与实现

大数据可视化项目——基于Python豆瓣电影数据可视化分析系统的设计与实现 2024最新项目 项目介绍 本项目旨在通过对豆瓣电影数据进行综合分析与可视化展示&#xff0c;构建一个基于Python的大数据可视化系统。通过数据爬取收集、清洗、分析豆瓣电影数据&#xff0c;我们提供了…

Docker:使用编排Compose快速部署容器化应用

1、简述 Docker Compose 是 Docker 官方提供的一个工具&#xff0c;用于定义和管理多容器应用。它通过一个简单的 YAML 文件来定义应用的服务、网络、卷等配置&#xff0c;并提供了一组命令来启动、停止、构建和管理应用。使用 Docker Compose 可以让开发人员轻松地在本地开发…

cdn加速与ssl加速

cdn CDN的全称是Content Delivery Network&#xff0c;即内容分发网络。其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节&#xff0c;使内容传输的更快、更稳定。 简单的来说&#xff0c;就是把原服务器上数据复制到其他服务器上&#xff0c;用户访…

蓝桥杯——松散子序列

题目 分析 很明显的动态规划问题&#xff0c;每次我们都取当前位置的最大值就可&#xff0c;从头开始&#xff0c;dp[i]max(dp[i-2],dp[i-3])num[i-3]. 代码 ninput() num[] for i in n:num.append(ord(i)-96) dp[0]*(len(num)3) for i in range(3,len(num)3):dp[i]max(dp[i…

锁策略总结

锁策略 悲观锁和乐观锁 乐观锁和悲观锁不是具体类型的锁而是指两种不同的对待加锁的态度&#xff0c;这两个锁面对锁冲突的态度是相反的。 乐观锁&#xff1a;认为不存在很多的并发操作&#xff0c;因此不需要加锁。悲观锁&#xff1a;认为存在很多并发操作&#xff0c;因此需…

什么是企微文档?怎样搭建企微文档?

企微文档作为一种高效、便捷的协作工具&#xff0c;已经有越来越多企业的在使用。那么&#xff0c;什么是企微文档&#xff1f;我们又该如何高效搭建企微文档呢&#xff1f;这就是我们今天要来探讨的问题。 | 什么是企微文档 简单来说&#xff0c;企微文档就是企业微信平台上的…

FFmpeg: 自实现ijkplayer播放器--06封装打开和关闭stream

文章目录 流程图stream openstream close流程图 stream open 初始化SDL以允许⾳频输出;初始化帧Frame队列初始化包Packet队列初始化时钟Clock初始化音量创建解复用读取线程read_thread创建视频刷新线程video_refresh_threadint FFPlayer::stream_open(const char

ASUS华硕ROG幻13笔记本电脑GV301R工厂模式原厂OEM预装Windows11系统,恢复出厂开箱状态

适用于型号&#xff1a;GV301RC、GV301RE、GV301RA 工厂模式安装包&#xff1a;https://pan.baidu.com/s/1gLme1VqidpUjCLocgm5ajQ?pwddnbk 提取码&#xff1a;dnbk 工厂模式Win11安装包带有ASUS RECOVERY恢复功能、自带所有驱动、出厂主题壁纸、系统属性专属联机支持标志…

#新版Onenet云平台使用(ESP8266 AT指令上报数据以及公网MQTT服务器连接测试)

1.上云方式&#xff1a;MQTT 参考&#xff1a; 新版ONENET物联网开放平台ATMQTT指令连接_at指令连接onenet的mqtt-CSDN博客https://blog.csdn.net/lilbye/article/details/131770196 ESP8266-01s入门&#xff1a;AT指令讲解、上云与MQTT通信教程-物联沃-IOTWORD物联网https:…

力扣:49. 字母异位词分组

知识点&#xff1a; 散列函数 散列函数能使对一个数据序列的访问过程更加迅速有效&#xff0c;通过散列函数&#xff0c;数据元素将被更快地定位&#xff1a; 1. 直接寻址法&#xff1a;取关键字或关键字的某个线性函数值为散列地址。即H&#xff08;key&#xff09;key或H&a…

蓝桥杯物联网竞赛_STM32L071_16_EEPROM

仍然是没有考过的知识点 朴素的讲就是板子中一块不会因为断电重启而导致数值初始化的一片地址 要注意的是有时候容易把板子什么写错导致板子什么地址写坏了导致程序无法烧录&#xff0c;这个时候记得一直按flash键烧录&#xff0c;烧录时会报错&#xff0c;点击确定&#xff0…

linux的线程概念

目录 1.原理 2.线程的周边概念 3.创建线程的接口 1.pthread_create 2.pthread_join 3.pthread_detach 4.终止线程 5.C11封装的多线程库 4.线程库的大概结构 5.__thread&#xff08;只能修饰内置类型&#xff09; 6.线程的互斥 1.了解原理 2.加锁 1.接口 2.代码示…