【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-...
相关推荐
运维@小兵2 小时前
vue开发用户注册功能
前端·javascript·vue.js
EndingCoder2 小时前
跨平台移动开发框架React Native和Flutter性能对比
flutter·react native·react.js
香蕉可乐荷包蛋4 小时前
vue数据可视化开发echarts等组件、插件的使用及建议-浅看一下就行
vue.js·信息可视化·echarts
老马啸西风4 小时前
sensitive-word-admin v2.0.0 全新 ui 版本发布!vue+前后端分离
vue.js·ui·ai·nlp·github·word
湛海不过深蓝5 小时前
【ts】defineProps数组的类型声明
前端·javascript·vue.js
layman05285 小时前
vue 中的数据代理
前端·javascript·vue.js
layman05285 小时前
vue中理解MVVM
前端·javascript·vue.js
鸡鸭扣7 小时前
DRF/Django+Vue项目线上部署:腾讯云+Centos7.6(github的SSH认证)
前端·vue.js·python·django·腾讯云·drf
sunbyte8 小时前
Three.js + React 实战系列 - 职业经历区实现解析 Experience 组件✨(互动动作 + 3D 角色 + 点击切换动画)
javascript·react.js·3d
2401_831943328 小时前
Element Plus对话框(ElDialog)全面指南:打造灵活弹窗交互
前端·vue.js·交互