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

server/2025/1/16 3:36:46/

使用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.ppmy.cn/server/1728.html

相关文章

【YOLOv5】使用yolov5训练模型时报错合集

文章目录 前言问题1 -- VsCode终端无法进入Anaconda创建的虚拟环境【问题描述】【问题分析】【解决方式】方法一方法二 问题2 -- 怎么在VsCode中为项目配置Anaconda创建的虚拟环境【问题描述】【解决方式】 问题3 -- yolov5训练模型时报错RuntimeError: result type Float cant…

【ElasticSearch】安装(bug篇)

以下解决办法参考自网友们的分享 1. JDK绑定问题 但其实这样也没有问题&#xff0c;因为内嵌的jdk版本与当前的es版本是适配的 但是&#xff0c;如果内嵌的jdk与当前es不适配&#xff0c;那就要修改配置文件 / 添加环境变量&#xff0c;让es启动的时候能扫描到我们本地的jdk …

Jmeter配置服务器监控插件

1.安装插件管理器 插件官网地址&#xff1a;JMeter Plugins :: JMeter-Plugins.org 点击 Plugins Manager,如上图所示&#xff0c; &#xff0c;点击jar file下载“plugins-manager.jar”&#xff0c;下载后放到“jmeter\lib\ext”目录下&#xff0c;重启jmeter。 2.安装资源…

001-谷粒商城-微服务剖析

1、架构图 还是很强的&#xff0c;该有的都有 2、微服务模块 SpringCloudAlibaba组件包括 SentinelNacosRocketMQSeata 搭配SpringCloudAlibaba组件 OpenFeignGateWayRibbn gateway使用了SpringWebFlux&#xff0c;前几天研究到&#xff0c;为什么springboot不直接使用Spri…

Python项目2 数据可视化

生成数据 数据可视化 指的是通过可视化表示来探索数据&#xff0c;它与数据挖掘 数据挖掘 紧密相关&#xff0c;而数据挖掘指的是使用代码来探索数据集的规律和关联。数据集可以是用一行代码就能表 示的小型数字列表&#xff0c;也可以是数以吉字节的数据。 漂亮地呈现数据关…

基于STM32的RFID智能门锁系统

本文针对RFID技术&#xff0c;着重研究了基于单片机的智能门锁系统设计。首先&#xff0c;通过链接4*4按键模块与主控STM32&#xff0c;实现了多种模式&#xff0c;包括刷卡开锁、卡号权限管理、密码开锁、修改密码、显示实时时间等功能。其次&#xff0c;采用RC522模块与主控S…

NVIDIA NCCL 源码学习(十四)- NVLink SHARP

背景 上节我们介绍了IB SHARP的工作原理&#xff0c;进一步的&#xff0c;英伟达在Hopper架构机器中引入了第三代NVSwitch&#xff0c;就像机间IB SHARP一样&#xff0c;机内可以通过NVSwitch执行NVLink SHARP&#xff0c;简称nvls&#xff0c;这节我们会介绍下NVLink SHARP如…

MySql的SQL语句

文章目录 MySql的SQL语句SQL通用语法SQL分类数据类型DDL数据库操作表操作查询创建修改删除 DML介绍添加数据修改数据删除数据 DQL介绍语法基本查询条件查询聚合函数分组查询排序查询分页查询执行顺序 DCL介绍管理用户权限控制 MySql的SQL语句 SQL通用语法 SQL语句可以单行或多…