【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-...
相关推荐
freewlt5 小时前
React Server Components 深度解析
前端·react.js·前端框架
卸任8 小时前
别用Quill了,打造自己的Tiptap富文本编辑器
前端·react.js
M ? A8 小时前
Vue 的 scoped 样式穿透 React 不支持?用 VuReact 编译就行
前端·javascript·vue.js·react.js·面试·开源·vureact
web打印社区8 小时前
[特殊字符] 开源好物:web-print-pdf,让 Web 打印像调用接口一样简单!
前端·javascript·vue.js·electron
岩岩很哇塞!10 小时前
【vue实现模仿探探卡片滑动切换效果】
前端·javascript·vue.js
kyriewen1112 小时前
Next.js:让你的React应用从“裸奔”到“穿衣服”
开发语言·前端·javascript·react.js·设计模式·ecmascript
茅盾体13 小时前
React Native
android·react native·react.js
军军君0113 小时前
数字孪生监控大屏实战模板:固体颗粒物监管平台
前端·javascript·vue.js·typescript·前端框架·echarts·less
前端那点事14 小时前
Cookie和Token的核心区别(附使用场景,易懂好记)
前端·vue.js