【react/vue】另一种管理表单状态的方法

最近读到了一篇文章:Stop Using State for React Forms, There is a Much Better Way!

说的是在react中,有另外一种更好的方法来存储表单的值

1、state不好在哪里?

在react中,当组件的state或者props变化时,就会重新渲染组件,更新试图

当我们使用state来存储表单的状态时,每次输入都会导致试图重新渲染

JavaScript 复制代码
import { useEffect, useState } from "react";

export default function FormWithState() {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

  function handleSubmit(e) {
    e.preventDefault();
    console.log({ email, password });
  }

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>邮箱</label>
        <input 
          value={email}
          onChange={(e) => setEmail(e.target.value)}
        />
      </div>
      <div>
        <label>密码</label>
        <input
          type="password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
        />
      </div>
      <button type="submit">提交</button>
    </form>
  );
}

但这种渲染在大多数情况下是没有必要的,一般我们只需要在最后点击按钮的时候获取到值即可;有一种方法可以用来避免重新渲染,那就是:使用FormData!

2、使用FormData来处理表单

使用js中的FormData原生接口,只需要将form表单元素传给构造函数FormData,它会自动填充表单值

JavaScript 复制代码
new Form(form)

并给form表单中的元素一个name属性,用于获取对应的值

具体做法如下:

JavaScript 复制代码
import { useEffect, useState } from "react";

export default function FormWithState() {

  function handleSubmit(e) {
    e.preventDefault();

    const form = new Form(e.currentTarget)
    // 获取对应的值
    const email = form.get('email'),
      password = form.get('password')
    console.log({ email, password });
  }

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>邮箱</label>
        <input 
          name="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
        />
      </div>
      <div>
        <label>密码</label>
        <input
          name="password"
          type="password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
        />
      </div>
      <button type="submit">提交</button>
    </form>
  );
}

3、在vue中是否也存在该问题

答案:是的

vue中的表单使用v-model这个语法糖来实现双向数据绑定,,当它的本质也是通过监听输入框的input事件,然后将表单最新的值存储在一个变量中,然后再将该变量与value属性绑定在一起

而这个变量通常是一个响应式数据,我们都知道vue基于依赖追踪来确定组件是否渲染,当响应式数据变化的时候,视图会重新渲染

这就导致每次输入视图都会重新渲染

所以在vue中的表单中使用FormData同样可以达到优化的效果

总结

本文只要总结Stop Using...这篇文章

不管是react还是vue,当状态发生变化的时候,组件会重新渲染;而form表单是一个频繁改变状态的标签,所以当我们使用响应式api来存储表单状态的时候,会导致每次输入组件都重新渲染

当我们只需要在最后提交时使用form状态的时候,我们可以在这个时候再去获取form的状态,这样就不需要维护状态变量,自然也就可以避免组件重复渲染的问题

所以,我们可以在最后通过获取对应的input标签来获取它的值;不过,有一种更简单的办法:使用FormData

  • 把获取值委托给FormData,它可以轻松捕获对应的数据

参考:

  1. hackernoon.com/stop-using-...
相关推荐
雪芽蓝域zzs15 小时前
第 7 节:多边形点击弹窗 + 清空绘制按钮
vue.js
溪语流沙15 小时前
【Web全栈进阶】Composition API与组件通信:props深入、emit、插槽
前端·css·vue.js
Misnearch17 小时前
React中的回调
前端·javascript·react.js
顽疲18 小时前
Java vue 养老系统源码详解:入住核算单 live-check 缴费入账与预交金收据实践
java·vue.js·python·java 养老·springboot 养老·vue养老
志尊宝19 小时前
Vue3 零基础每日笔记(088·完结):从零到一——一个完整 Vue3 项目的成长复盘
前端·javascript·vue.js·笔记·ecmascript·#vue.js
桔筐20 小时前
Vue中DOM的data-*自定义属性(dataset)与Vue data响应式变量区别详解
前端·javascript·vue.js
用户17335980753721 小时前
纯前端 PDF 按书签拆分避坑指南:拆分后章节对不上?
前端·javascript·vue.js
雪芽蓝域zzs1 天前
Webstorm打开uniapp uvue文件报红处理方案
vue.js
Java后端的Ai之路1 天前
09-React组件生命周期
前端·react.js·前端框架
撸串-研究生1 天前
面向景区的综合服务管理平台设计——以稻城亚丁景区为例【附源码】
java·开发语言·vue.js·前后端分离·稻城亚丁景区