【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-...
相关推荐
im_AMBER1 小时前
React 18
前端·javascript·笔记·学习·react.js·前端框架
老前端的功夫1 小时前
Vue2中key的深度解析:Diff算法的性能优化之道
前端·javascript·vue.js·算法·性能优化
han_2 小时前
前端高频面试题之Vue(高级篇)
前端·vue.js·面试
Dm_dotnet3 小时前
React:使用Tailwind CSS、Streamdown与Ant Design X
react.js
脸大是真的好~3 小时前
黑马JAVAWeb -Vue工程化-API风格 - 组合式API
前端·javascript·vue.js
你挚爱的强哥3 小时前
【sgMobileUploadTypeSelect】自定义组件:从底部弹出选择上传图片文件的方式【1、上传本地文件,2、拍摄上传】
前端·javascript·vue.js
LXA08094 小时前
Vue 3中使用JSX
前端·javascript·vue.js
执携4 小时前
Vue Router (历史模式)
前端·javascript·vue.js
G018_star sky♬4 小时前
使用npm运行js脚本覆盖vue依赖包
javascript·vue.js
宇余4 小时前
从 useState 到 URLState:前端状态管理的另一种思路
前端·vue.js