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

免费做h5的网站小程序制作开发平台

免费做h5的网站,小程序制作开发平台,天津建设工程信息网官网平台,网站域名如何使用方法前言 useSubmit 是 React Router v6.4 引入的强大钩子&#xff0c;用于以编程方式提交表单数据。 它提供了对表单提交过程的精细控制&#xff0c;特别适合需要自定义提交行为或非标准表单场景的应用。 一、useSubmit 核心用途 编程式表单提交&#xff1a;不依赖 <form>…

前言

useSubmitReact Router v6.4+ 引入的强大钩子,用于以编程方式提交表单数据。
它提供了对表单提交过程的精细控制,特别适合需要自定义提交行为或非标准表单场景的应用。

一、useSubmit 核心用途

  1. 编程式表单提交:不依赖 <form> 元素手动提交数据
  2. 自定义提交逻辑:在提交前/后执行额外操作
  3. 动态表单构建:根据应用状态生成提交数据
  4. 替代传统表单:在复杂UI中实现表单功能

二、useSubmit 基本用法

import { useSubmit } from 'react-router-dom';function CustomSubmitButton() {const submit = useSubmit();const handleSubmit = () => {// 构建表单数据const formData = new FormData();formData.append('username', 'john_doe');formData.append('password', 'secure123');// 提交数据submit(formData, {method: 'post',action: '/login',encType: 'application/x-www-form-urlencoded'});};return (<button onClick={handleSubmit}>登录</button>);
}

三、useSubmit 参数详解

3.1、submit 函数参数

```javascript
submit(data: FormData | URLSearchParams | { [key: string]: string } | null,options?: {method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';action?: string;encType?: 'application/x-www-form-urlencoded' | 'multipart/form-data';replace?: boolean;}
)
```

3.2、选项说明:

method:HTTP方法(默认为"GET")
action:提交的目标URL(默认为当前URL
encType:表单编码类型(默认为"application/x-www-form-urlencoded")
replace:是否替换历史记录而不是添加新条目(默认为false

四、useSubmit 实际应用场景

4.1、自定义删除按钮

import { useSubmit } from 'react-router-dom';function DeleteButton({ itemId }) {const submit = useSubmit();const handleDelete = () => {if (window.confirm('确定要删除此项吗?')) {submit({ id: itemId }, { method: 'delete', action: `/items/${itemId}` });}};return (<button onClick={handleDelete}className="delete-btn"aria-label="删除项目">🗑️ 删除</button>);
}

4.2、动态搜索表单

import { useState, useEffect } from 'react';
import { useSubmit, useLocation } from 'react-router-dom';function SearchBar() {const submit = useSubmit();const location = useLocation();const [query, setQuery] = useState('');// 使用防抖自动提交搜索useEffect(() => {const timerId = setTimeout(() => {if (query.trim() !== '') {const formData = new FormData();formData.append('q', query);submit(formData, {method: 'get',action: '/search',replace: query === '' // 空查询时替换历史记录});}}, 300);return () => clearTimeout(timerId);}, [query, submit]);// 初始化时从URL读取查询参数useEffect(() => {const params = new URLSearchParams(location.search);setQuery(params.get('q') || '');}, [location.search]);return (<div className="search-container"><inputtype="text"value={query}onChange={(e) => setQuery(e.target.value)}placeholder="搜索..."className="search-input"/>{query && (<button onClick={() => setQuery('')}className="clear-btn"></button>)}</div>);
}

4.3、多步骤表单

import { useState } from 'react';
import { useSubmit } from 'react-router-dom';function MultiStepForm() {const submit = useSubmit();const [step, setStep] = useState(1);const [formData, setFormData] = useState({personal: {},address: {},preferences: {}});const handleNextStep = () => {if (step < 3) {setStep(step + 1);} else {// 最终提交submitForm();}};const handlePrevStep = () => {setStep(step - 1);};const updateFormData = (section, data) => {setFormData(prev => ({...prev,[section]: { ...prev[section], ...data }}));};const submitForm = () => {// 构建完整表单数据const finalData = {...formData.personal,...formData.address,...formData.preferences};submit(finalData, {method: 'post',action: '/register',encType: 'application/json'});};return (<div className="multi-step-form"><div className="progress-bar"><div className={`step ${step >= 1 ? 'active' : ''}`}>个人信息</div><div className={`step ${step >= 2 ? 'active' : ''}`}>地址信息</div><div className={`step ${step >= 3 ? 'active' : ''}`}>偏好设置</div></div><div className="form-content">{step === 1 && (<PersonalInfo data={formData.personal}onChange={data => updateFormData('personal', data)}/>)}{step === 2 && (<AddressInfo data={formData.address}onChange={data => updateFormData('address', data)}/>)}{step === 3 && (<Preferences data={formData.preferences}onChange={data => updateFormData('preferences', data)}/>)}</div><div className="form-navigation">{step > 1 && (<button onClick={handlePrevStep}>上一步</button>)}<button onClick={handleNextStep}>{step < 3 ? '下一步' : '提交注册'}</button></div></div>);
}

4.4、文件上传

import { useRef, useState } from 'react';
import { useSubmit } from 'react-router-dom';function FileUploader() {const submit = useSubmit();const fileInputRef = useRef(null);const [isUploading, setIsUploading] = useState(false);const [progress, setProgress] = useState(0);const handleFileChange = async (e) => {const file = e.target.files[0];if (!file) return;setIsUploading(true);try {// 创建FormData对象const formData = new FormData();formData.append('file', file);formData.append('description', '用户上传的文件');// 创建XMLHttpRequest以获取上传进度const xhr = new XMLHttpRequest();// 进度事件处理xhr.upload.addEventListener('progress', (event) => {if (event.lengthComputable) {const percent = Math.round((event.loaded / event.total) * 100);setProgress(percent);}});// 完成事件处理xhr.addEventListener('load', () => {setIsUploading(false);setProgress(0);alert('文件上传成功!');});// 错误处理xhr.addEventListener('error', () => {setIsUploading(false);alert('文件上传失败');});// 打开并发送请求xhr.open('POST', '/upload');xhr.send(formData);// 或者使用submit钩子(但无法获取进度)// submit(formData, {//   method: 'post',//   action: '/upload',//   encType: 'multipart/form-data'// });} catch (error) {setIsUploading(false);console.error('上传失败:', error);}};return (<div className="file-uploader"><input type="file" ref={fileInputRef} onChange={handleFileChange}style={{ display: 'none' }} /><button onClick={() => fileInputRef.current.click()}disabled={isUploading}>选择文件</button>{isUploading && (<div className="upload-progress"><div className="progress-bar" style={{ width: `${progress}%` }}></div><span>{progress}%</span></div>)}</div>);
}

4.5、乐观更新与表单提交

import { useState } from 'react';
import { useSubmit } from 'react-router-dom';function TodoItem({ todo }) {const submit = useSubmit();const [isCompleted, setIsCompleted] = useState(todo.completed);const [isUpdating, setIsUpdating] = useState(false);const handleToggle = async () => {// 乐观更新:立即更新UIconst newCompleted = !isCompleted;setIsCompleted(newCompleted);setIsUpdating(true);try {// 准备表单数据const formData = new FormData();formData.append('id', todo.id);formData.append('completed', newCompleted.toString());// 提交更新submit(formData, {method: 'patch',action: `/todos/${todo.id}`,encType: 'application/x-www-form-urlencoded'});} catch (error) {// 出错时回滚状态setIsCompleted(!newCompleted);console.error('更新失败:', error);} finally {setIsUpdating(false);}};return (<li className={`todo-item ${isCompleted ? 'completed' : ''}`}><inputtype="checkbox"checked={isCompleted}onChange={handleToggle}disabled={isUpdating}/><span className="todo-text">{todo.text}</span>{isUpdating && <span className="updating-indicator">更新中...</span>}</li>);
}

五、useSubmit 与相关API对比

在这里插入图片描述

六、useSubmit 最佳实践

  1. 数据验证:提交前验证数据

  2. 用户反馈:提交时显示加载状态

  3. 错误处理:捕获并处理提交错误

  4. 编码类型:

    a.简单数据:application/x-www-form-urlencoded

    b.文件上传:multipart/form-data

    c.JSON数据:手动序列化并设置适当headers

  5. 性能优化:大文件上传使用分块或流式上传

// 带验证的提交示例
function ValidatedForm() {const submit = useSubmit();const [email, setEmail] = useState('');const [error, setError] = useState('');const handleSubmit = () => {// 验证邮箱格式if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {setError('请输入有效的邮箱地址');return;}// 提交数据submit({ email }, { method: 'post', action: '/subscribe' });};return (<div className="subscribe-form"><inputtype="email"value={email}onChange={(e) => {setEmail(e.target.value);setError('');}}placeholder="输入您的邮箱"className={error ? 'error' : ''}/>{error && <div className="error-message">{error}</div>}<button onClick={handleSubmit}>订阅</button></div>);
}

七、useSubmit 注意事项

  1. 路由上下文:必须在路由组件中使用(在 <Router> 上下文中)

  2. 数据格式:

    对象会被转换为 URLSearchParams

    文件上传必须使用 FormData

  3. GET请求:数据会作为查询参数添加到URL

  4. 重定向:提交后服务器应返回重定向响应

  5. 状态管理:提交不会自动管理加载状态,需自行实现

总结

useSubmitReact Router 中处理表单提交的高级工具,特别适合以下场景:

  1. 自定义表单逻辑:当需要超出标准表单的行为时
  2. 动态数据提交:根据应用状态生成提交数据
  3. 非表单元素提交:从按钮或其他UI元素触发提交
  4. 复杂交互流程:如多步骤表单、乐观更新
  5. 文件上传:处理二进制数据提交

通过合理使用 useSubmit,您可以构建更灵活、更强大的表单交互体验,同时保持与 React Router 数据路由模型的无缝集成

http://www.dtcms.com/a/587960.html

相关文章:

  • 重庆网站建设中心wordpress信用卡
  • 临清网站建设公司最近的新闻事件
  • 做散客机票的网站如何推广注册城乡规划师一年能挂多少钱
  • seo怎么做自己的网站玉环住房与城乡建设规划局网站
  • 自助建设网站软件软件公司薪酬绩效方案
  • 0基础网站搭建教程百度数据平台
  • 深度科技商业官方网站手机网站格式商城
  • 广州外贸营销型网站兰州起点网站建设
  • 网站建设方案对比分析报告seo谷歌外贸推广
  • 上网建站全国十大室内设计师
  • 网站建设和电子商务的关系公司网站建设费计入什么科目
  • 高州手机网站建设公司甘肃省建设局网站首页
  • 亚马逊网站运营怎么做站长之家网页模板
  • 西安网站制作定制济南传承网络李聪
  • 莆田网站建设模板工资卡app下载
  • 做二手车广告推广哪家网站好网站优化过度被k
  • 公司网站地图怎么做用ps设计一个个人网站模板
  • 淄博汽车网站建设建设集团网站方案设计
  • 重庆网站优化seo公司模板建站多少钱
  • 网站建设域名注册图片站wordpress模板下载
  • 陕西省城乡建设网站dedecms如何做音乐网站
  • 泉州模板建站公司网站建设案例策划
  • 外贸建站模板价格江西航达建设集团网站
  • 在网站上做网络课堂软件多少钱wordpress添加继续阅读
  • 阿里云做的网站误删了富德生命人寿保险公司官方网站
  • 网站建设实验结论酒店网站建设案例策划书怎么写
  • 去掉wordpress版权网站东莞优化建设
  • 企业建设营销型网站步骤网站链接失效怎么做
  • 单页网站建设wordpress 快讯
  • wordpress网站数据库备份网站建设及推广预算表