美文网首页
【转】form元素是React的未来

【转】form元素是React的未来

作者: 涅槃快乐是金 | 来源:发表于2023-05-30 23:39 被阅读0次

    大家好,我卡颂。

    请思考一个问题:如果有一个HTML标签,React围绕他专门出了2个hook,那这个标签对React未来的发展一定非常重要,这没毛病吧?

    这个标签就是 —— form

    React围绕form新出了如下2个hook

    • useOptimistic
    • useFormStatus

    本文会聊聊React围绕form的布局与发展。

    欢迎加入人类高质量前端交流群,带飞

    Next.js的发展历程

    说到React未来的发展,必须从Next.js聊起。毕竟,React团队成员不是加入Next团队,就是在加入的路上。

    web开发中涉及到前后端交互的部分主要包括:

    1. 根据后端数据渲染前端页面
    2. 根据前端用户输入保存数据到后端

    Next.js的发展主要围绕以上两点展开。

    根据后端数据渲染前端页面

    前期,Next.js的主打特性是SSRSSG。也就是把根据后端数据渲染前端页面的过程从前端挪到后端。

    这个时期的Next.js路由被称为Pages Router

    时间来到Next.js v13,以RSC(React Server Component)为核心的App Router取代Pages Router成为默认配置。

    [图片上传失败...(image-bceb8d-1685547417125)]

    很多朋友不熟悉RSC,认为他是实验特性。实际上,RSC借由Next.js已经落地了。

    一句话理解RSC —— 客户端组件(在浏览器渲染的React组件)可以根据依赖分为两部分:

    • 依赖数据源(比如数据库、文件系统)的组件,可以作为RSC(服务端组件)
    • 依赖状态(比如statepropscontext)的组件,可以作为客户端组件

    根据后端数据渲染前端页面角度看:

    • SSRSSG是页面级别的(服务端渲染呈现的是整个页面)
    • RSC是组件级别的(服务端组件请求数据源)

    根据前端用户输入保存数据到后端

    聊完了根据后端数据渲染前端页面,那么,围绕根据前端用户输入保存数据到后端Next.js能做哪些优化?

    这就要提到Next.js的实验特性 —— Server Action

    Server Action

    根据前端用户输入保存数据到后端的常见场景是表单提交,通常我们会在formobSubmit事件中做后续处理:

    function Form() {
      function submit() {
        // ...处理formData的逻辑
        // ...发送请求的逻辑
      }
      return (
        <form onSubmit={submit}>
          <input type="text"/>
          <input type="text"/>
        </form>
      )
    }
    

    以上代码有什么可改进的地方呢?

    从用户体验的角度看,如果前端禁用了JS,那么React不能运行,上述交互失效。如果在禁用JS的情况下也能提交表单就好了。

    从开发体验的角度看,submit方法会发起请求,后端再根据请求携带的formData操作数据库,比较繁琐。如果在submit方法内能直接操作数据库就好了。

    Server Action特性就是为了实现以上2个目标。

    首先来看第一个目标。

    目标1

    HTML原生的form元素有个action属性,可以接收一个url。当提交表单(比如点击typesubmit的按钮)后formData会提交给该url

    <form action="/action_page.php" method="get">
      <label for="fname">First name:</label>
      <input type="text" id="fname" name="fname"><br><br>
      <label for="lname">Last name:</label>
      <input type="text" id="lname" name="lname"><br><br>
      <input type="submit" value="Submit">
    </form>
    

    由于提交表单的行为是HTML原生支持的,所以在禁用JS的情况下也能执行。

    这就是禁用JS也能提交表单的理论基础。

    目标2

    React扩展了formaction属性,让他除了支持url,还能支持回调函数,比如:

    function App() {
      function submit(data) {
        // ...
      }
      return (
        <form action={submit}>
          <! -- 省略 -->
        </form>
      );
    

    如果这个回调函数内是前端执行的逻辑,则被称为client action,比如下面这样:

     async function submit(data) {
        await const res = saveData(data);
        // ...
      }
    

    如果这个函数内是后端执行的逻辑,则被称为server action,比如下面这样:

     "use server"
    
      async function submit(data) {
        const userID = cookies().get("userID")?.value;
        await db.users.update(userID, data);
        // ...
      }
    

    "use server"标记代表这是个server action

    如果是server action,那么发起的请求类型是multipart/form-data(即表单提交):

    响应类型则是RSC协议

    也就是说,有了server action,开发者可以直接在formaction属性(或者buttonformAction属性等其他几种属性)内书写后端逻辑,并且在浏览器禁用JS的情况下这些逻辑也能执行。

    2个新hook

    为了更好的服务server actionReact团队新出了2个hook用于提高form场景下的用户体验:

    • useOptimistic
    • useFormStatus

    当前,这2个hook的介绍只能在Next.js文档(而不是React文档)中看到。

    useOptimistic主要用来优化提交数据的用户体验。

    比如,在点赞的场景,通常逻辑是:

    1. 点击点赞按钮
    2. 发起点赞请求
    3. 点赞成功,前端显示点赞效果

    但为了用户体验的流畅,前端通常会把逻辑做成:

    1. 点击点赞按钮
    2. 前端显示点赞效果(同时发起点赞请求)
    3. 根据请求结果,如果点赞成功则不做处理,如果点赞失败则重置按钮

    useOptimistic的本质就是在状态层面实现上述效果。

    useFormStatus则用于在表单提交过程中显示pending状态:

    function ButtonDisabledWhilePending({action, children}) {
      const {pending} = useFormStatus();
      return (
        <button disabled={pending} formAction={action}>
          {children}
        </button>
      );
    }
    

    有同学可能会疑惑:useFormStatus没有传参,他怎么知道对应哪个form

    实际上,为了实现useFormStatusReact在源码内为所有HostComponent(即原生HTML元素对应组件,比如<div/>)定制了一个context

    当某个form触发表单提交时,context的值会被更新为这个form的数据。useFormStatus本身仅仅是useContext(上述context)

    总结

    可以发现,不管是useFormStatususeOptimistic还是最近1~2年新出的hook(比如useIduseMutableSource),我们开发者都很少会用到。

    因为这些hook都是为上层框架(主要是Next.js)提供的。

    React早已完成他作为前端框架的使命。在他生命的后半程,他将作为上层框架的操作系统而存在。

    server actionNext.js的未来,Next.jsReact的未来。所以,React的未来会围绕form元素持续布局。

    原文:https://segmentfault.com/a/1190000043848506

    相关文章

      网友评论

          本文标题:【转】form元素是React的未来

          本文链接:https://www.haomeiwen.com/subject/psneedtx.html