前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >React 新 hook:useFormStatus 使用详解

React 新 hook:useFormStatus 使用详解

作者头像
用户6901603
发布2024-05-28 12:40:50
1440
发布2024-05-28 12:40:50
举报
文章被收录于专栏:不知非攻不知非攻

本文内容梗概

  • action 支持异步回调
  • useFormStatus 基础知识
  • 使用 useFormStatus 获得提交状态
  • 案例:提交表单时禁止输入

全文共 2213 字,阅读需要花费 4 分钟

1、action 支持异步回调

一个令人振奋的特性就是,在 React19 中,action 支持传入异步回调函数。

例如如下代码

代码语言:javascript
复制
async function formAction(formdata) {
  const title = formdata.get('title')
  const content = formdata.get('content')

  // 简单校验
  if (!title || !content) {
    return;
  }

  await new Promise(resolve => setTimeout(resolve, 1000))
  setPosts(posts => [...posts, {title,content}])
}
代码语言:javascript
复制
<form action={formAction}>
  ...
</form>

有了这个特性的支持,我们就可以非常方便的利用它来实现一些上传逻辑。不过一个小小的需求就是,点击提交之后,接口请求的过程中,我们希望按钮处于禁用状态,那应该怎么办呢?

React 19 提供了名为 useFormStatus 的 hook 来帮助我们做到这个事情。

2、useFormStatus

和别的 hook 不同的是,我们需要从 react-dom 中获取到它的引用

代码语言:javascript
复制
import { useFormStatus } from "react-dom";

useFormStatus 能够在 form 元素的子组件中,获取到表单提交时的 pending 状态和表单内容。

与 form 同属于一个组件,获取不到,只能是封装后的子组件才能获取到

代码语言:javascript
复制
const { pending, data, method, action } = useFormStatus();

pending 为 true 时,表示请求正在进行。我们可以利用这个值的变化在提交按钮上设置 Loading 样式

data 格式为 FormData,表示此次提交里表单的所有内容。

method 表示我们在提交时,所采用的请求方式,默认值为 get

需要注意的是,提交方式并不需要通过如下方式设置,这样做会报错。

代码语言:javascript
复制
<form method="post">

</form>

action 就是在 form 元素中的 action 回调函数的引用。

3、案例一:提交时设置禁用按钮

为了防止重复提交,我们希望在提交时就马上禁用按钮,等到提交完成之后再恢复按钮的点击。与此同时,我们可能还需要在 UI 交互上做出一些提示,让用户知道当前正在发送请求

交互效果如下

这里主要是针对提交按钮做的操作,因此我们需要单独将提交按钮相关的部分拿出来封装成为一个子组件,并在子组件中利用 useFormStatus 获取异步 action 的 pending 状态。

代码非常的简单,如下所示

代码语言:javascript
复制
function SubmitButton() {
  const {pending} = useFormStatus()
  
  return (
    <div className="form_item">
      <button
        className='primary'
        type='submit'
        disabled={pending}
      >
        {pending ? 'Submitting...' : 'Submit'}
      </button>      
    </div>
  )
}

然后在 form 元素中使用该组件即可

代码语言:javascript
复制
<form action={formAction} method="post">
  <div className="form_item">
    <div className="label">Title</div>
    <input name='title' type="text" placeholder='Enter title' />
  </div>

  <div className="form_item">
    <div className="label">Name</div>
    <input name='content' type="text" placeholder='Enter you name' />
  </div>
  
  <SubmitButton />
</form>

4、案例二:提交时禁止输入内容

通常情况下,我们也希望在表单提交时,不允许输入内容。useFormStatus 可以很容易帮我们做到这一点。

实现非常简单,我们将某一个字段单独封装到子组件中,利用 useFormStatus 提供的 pending 状态来判断是否禁用输入,代码如下

代码语言:javascript
复制
function Input2({required, name}) {
  const {pending} = useFormStatus()

  return (
    <div className="form_item">
      <div className="label">Name</div>
      <input
        name={name}
        type="text"
        placeholder='Enter you name'
        disabled={pending}
      />
    </div>
  )
}
代码语言:javascript
复制
<form action={formAction}>
  <div className="form_item">
    <div className="label">Title</div>
    <input name='title' type="text" placeholder='Enter title' />
  </div>

  <Input2 required name='content' />

  <SubmitButton />
</form>

5、总结

useFormStatus 是结合 action 异步请求时使用的 hook,它们是对 HTML 表单能力的增强。因此我们可以借助他们与 HTML 表单元素自身支持的特性实现更复杂的表单交互逻辑。

这里我们需要注意的是 action 与 onSubmit 的区别。onSubmit 会优先于 action 执行。并且,如果我们在 onSubmit 的回调函数中,使用了 preventDefault,action 回调将不会执行

代码语言:javascript
复制
function onSubmit(e) {
  e.preventDefault()
  // ...
}

在 onSubmit 中,我们可以结合 state,通过控制数据的行为来自定义表单行为,而无需过多依赖 HTML 表单元素本身的能力。具体如何抉择大家需要根据自身项目的需求情况来定。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 这波能反杀 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、action 支持异步回调
  • 2、useFormStatus
  • 3、案例一:提交时设置禁用按钮
  • 4、案例二:提交时禁止输入内容
  • 5、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档