You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何借助Formik与Yup验证表单后将数据存入localStorage

使用Formik+Yup验证表单后将数据存入localStorage

实现步骤

  1. 确保已安装依赖
    若未安装Formik和Yup,执行以下命令:

    npm install formik yup
    # 或
    yarn add formik yup
    
  2. 定义Yup验证规则
    根据你的四个输入框字段(示例用name/age/email/phone)编写验证Schema,确保提交前数据符合要求。

  3. 用Formik构建表单并处理提交逻辑
    Formik的onSubmit回调仅在验证通过后触发,刚好适合在这里处理localStorage存储。


组件式实现示例

import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as Yup from 'yup';

const UserForm = () => {
  // 验证规则
  const validationSchema = Yup.object({
    name: Yup.string().required('姓名不能为空'),
    age: Yup.number().min(18, '年龄需满18岁').required('年龄不能为空'),
    email: Yup.string().email('邮箱格式错误').required('邮箱不能为空'),
    phone: Yup.string().matches(/^1[3-9]\d{9}$/, '手机号格式错误').required('手机号不能为空'),
  });

  // 初始表单值,可选恢复历史数据
  const initialValues = {
    name: '',
    age: '',
    email: '',
    phone: '',
    // ...JSON.parse(localStorage.getItem('userFormData')) || {}
  };

  const handleSubmit = (validatedValues, { resetForm }) => {
    // 将验证后的JSON数据转为字符串存入localStorage
    localStorage.setItem('userFormData', JSON.stringify(validatedValues));
    // 可选:提交后重置表单
    resetForm();
    alert('表单数据已保存到localStorage');
  };

  return (
    <Formik
      initialValues={initialValues}
      validationSchema={validationSchema}
      onSubmit={handleSubmit}
    >
      <Form className="form-container">
        <div className="form-group">
          <label htmlFor="name">姓名</label>
          <Field type="text" id="name" name="name" className="form-input" />
          <ErrorMessage name="name" component="div" className="error-message" />
        </div>

        <div className="form-group">
          <label htmlFor="age">年龄</label>
          <Field type="number" id="age" name="age" className="form-input" />
          <ErrorMessage name="age" component="div" className="error-message" />
        </div>

        <div className="form-group">
          <label htmlFor="email">邮箱</label>
          <Field type="email" id="email" name="email" className="form-input" />
          <ErrorMessage name="email" component="div" className="error-message" />
        </div>

        <div className="form-group">
          <label htmlFor="phone">手机号</label>
          <Field type="text" id="phone" name="phone" className="form-input" />
          <ErrorMessage name="phone" component="div" className="error-message" />
        </div>

        <button type="submit" className="submit-btn">提交并保存</button>
      </Form>
    </Formik>
  );
};

export default UserForm;

Hooks式实现示例(useFormik)

若偏好钩子API,可使用以下写法:

import { useFormik } from 'formik';
import * as Yup from 'yup';

const UserForm = () => {
  const formik = useFormik({
    initialValues: {
      name: '',
      age: '',
      email: '',
      phone: '',
      // 可选:恢复历史数据
      // ...JSON.parse(localStorage.getItem('userFormData')) || {}
    },
    validationSchema: Yup.object({
      name: Yup.string().required('姓名不能为空'),
      age: Yup.number().min(18, '年龄需满18岁').required('年龄不能为空'),
      email: Yup.string().email('邮箱格式错误').required('邮箱不能为空'),
      phone: Yup.string().matches(/^1[3-9]\d{9}$/, '手机号格式错误').required('手机号不能为空'),
    }),
    onSubmit: (validatedValues) => {
      localStorage.setItem('userFormData', JSON.stringify(validatedValues));
      alert('数据保存成功');
    },
  });

  return (
    <form onSubmit={formik.handleSubmit} className="form-container">
      <div className="form-group">
        <label htmlFor="name">姓名</label>
        <input
          id="name"
          name="name"
          type="text"
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
          value={formik.values.name}
          className="form-input"
        />
        {formik.touched.name && formik.errors.name && (
          <div className="error-message">{formik.errors.name}</div>
        )}
      </div>

      <div className="form-group">
        <label htmlFor="age">年龄</label>
        <input
          id="age"
          name="age"
          type="number"
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
          value={formik.values.age}
          className="form-input"
        />
        {formik.touched.age && formik.errors.age && (
          <div className="error-message">{formik.errors.age}</div>
        )}
      </div>

      <div className="form-group">
        <label htmlFor="email">邮箱</label>
        <input
          id="email"
          name="email"
          type="email"
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
          value={formik.values.email}
          className="form-input"
        />
        {formik.touched.email && formik.errors.email && (
          <div className="error-message">{formik.errors.email}</div>
        )}
      </div>

      <div className="form-group">
        <label htmlFor="phone">手机号</label>
        <input
          id="phone"
          name="phone"
          type="text"
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
          value={formik.values.phone}
          className="form-input"
        />
        {formik.touched.phone && formik.errors.phone && (
          <div className="error-message">{formik.errors.phone}</div>
        )}
      </div>

      <button type="submit" className="submit-btn">提交并保存</button>
    </form>
  );
};

export default UserForm;

关键说明

  • 验证触发逻辑:Formik会在表单提交时自动执行Yup验证,仅当所有字段通过验证时才会进入onSubmit回调,确保存入localStorage的数据合法。
  • 数据存储格式:localStorage仅支持字符串存储,因此用JSON.stringify()将表单对象转为JSON字符串;后续读取时用JSON.parse(localStorage.getItem('userFormData'))即可还原为对象。
  • 持久化恢复:若需页面刷新后保留表单数据,直接在initialValues中读取localStorage的历史数据即可(代码中已注释示例)。
  • 存储限制:localStorage单域名下存储上限约5MB,避免存入过大数据。

内容的提问来源于stack exchange,提问作者Rajj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 21:55:18