formik介绍及基本使用

1 formik 简介

1.1 FormIk介绍

FormIk是React 官方推荐我们使用的用于增强表单功能的第三方组件库。使用了formik 我们就可以更加专注于我们的业务逻辑,而不用分心去处理表单基础上的一些细节。

它帮助我们增强表单的护理能力,简化表单处理流程。

1.2 FormIk 下载

npm install formik

2 FormIk增强表单

2.1 Formik 基本使用

使用formik 进行表单数据绑定以及表单提交处理

import { memo, useState } from 'react'
import { useFormik } from 'formik'

function App () {
  const formik = useFormik({
    initialValues: {
      username: '',
      password: ''
    },
    onSubmit: values => {
      // 这里formik 已经默认帮我们阻止了默认执行
      console.log(values)
    }
  })
  return (
    <div>
      <form onSubmit={formik.handleSubmit}>
        <label htmlFor='username'>用户名</label>
        <input
          type='text'
          name='username'
          value={formik.values.username}
          onChange={formik.handleChange}
        />
        <label htmlFor='password'>密码</label>
        <input
          type='password'
          name='password'
          value={formik.values.password}
          onChange={formik.handleChange}
        />
        <button type='submit'>提交</button>
      </form>
    </div>
  )
}

export default memo(App)

2.2 formik 表单验证

2.2.1 初始验证方式

在useFomik时配置validate属性,是一个函数,它接收表单的值,在函数内部可以对表单的值进行验证,该函数最终返回一个对象,对表单中的字段的验证错误结果进行描述。

2.2.3 完善验证错误信息时的用户体验

在提示错误信息时,通过 formik.touched.xxx 可以检查表单元素是否被改动过。在此之前,需要给input 的表达元素中添加 onBlur 事件处理函数 onBlur={formik.handleBlur},也就是当鼠标离开焦点时再开始验证。

import { memo } from 'react'
import { useFormik } from 'formik'

function App () {
  const formik = useFormik({
    // validateOnChange: false,
    // validateOnBlur: true,
    initialValues: {
      username: '',
      password: ''
    },
    onSubmit: values => {
      console.log(values)
    },
    validate: values => {
      const errors = {}
      if (!values.username || values.username.trim() === '') {
        errors.username = '用户名不能为空'
      } else if (values.username.length > 15) {
        errors.username = '用户名长度不能大于15位'
      }

      if (values.password.length < 6) {
        errors.password = '密码长度不能小于6位'
      }
      console.log('validate....', errors)
      return errors
    }
  })
  return (
    <div>
      <form onSubmit={formik.handleSubmit}>
        <div>
          <label htmlFor='username'>用户名</label>
          <input
            id='username'
            type='text'
            name='username'
            value={formik.values.username}
            onChange={formik.handleChange}
            onBlur={formik.handleBlur}
          />
          <p>
            {formik.touched.username && formik.errors.username
              ? formik.errors.username
              : null}
          </p>
        </div>
        <div>
          <label htmlFor='password'>密&nbsp;&nbsp;&nbsp;&nbsp;码</label>
          <input
            id='password'
            type='password'
            name='password'
            value={formik.values.password}
            onChange={formik.handleChange}
            onBlur={formik.handleBlur}
          />
          <p>
            {formik.touched.username && formik.errors.password
              ? formik.errors.password
              : null}
          </p>
        </div>
        <button type='submit'>提交</button>
      </form>
    </div>
  )
}

export default memo(App)

2.2.2 使用yup 验证表单

2.2.2.1 下载yup
npm install yup
2.2.2.2 如何使用yup
  • 定义验证规则

使用yup 配合Formik实现验证需要配置 validationSchema 选项, 配置为Yup.object({})所生产的一个对象,这时候我们就可以把validate函数拿掉,检验的代码就变得简洁多了,成为了编写描述对象的形式。而其他的没有变化。

import { memo } from 'react'
import { useFormik } from 'formik'
import * as Yup from 'yup'

function App () {
  const formik = useFormik({
    // validateOnChange: false,
    // validateOnBlur: true,
    initialValues: {
      username: '',
      password: ''
    },
    onSubmit: values => {
      console.log(values)
    },
    /* validate: values => {
      const errors = {}
      if (!values.username || values.username.trim() === '') {
        errors.username = '用户名不能为空'
      } else if (values.username.length > 15) {
        errors.username = '用户名长度不能大于15位'
      }

      if (values.password.length < 6) {
        errors.password = '密码长度不能小于6位'
      }
      console.log('validate....', errors)
      return errors
    } */
    // 使用yup 实现验证需要配置 validationSchema, 配置位Yup.object({})所生产的一个对象
    validationSchema: Yup.object({
      username: Yup.string()
        .max(15, '用户名长度不能大于15位')
        .required('请填写用户名'),
      password: Yup.string()
        .min(6, '密码长度不能小于6位')
        .required('请填写密码')
    })
  })
  return (
    <div>
      <form onSubmit={formik.handleSubmit}>
        <div>
          <label htmlFor='username'>用户名</label>
          <input
            id='username'
            type='text'
            name='username'
            value={formik.values.username}
            onChange={formik.handleChange}
            onBlur={formik.handleBlur}
          />
          <p>
            {formik.touched.username && formik.errors.username
              ? formik.errors.username
              : null}
          </p>
        </div>
        <div>
          <label htmlFor='password'>密&nbsp;&nbsp;&nbsp;&nbsp;码</label>
          <input
            id='password'
            type='password'
            name='password'
            value={formik.values.password}
            onChange={formik.handleChange}
            onBlur={formik.handleBlur}
          />
          <p>
            {formik.touched.username && formik.errors.password
              ? formik.errors.password
              : null}
          </p>
        </div>
        <button type='submit'>提交</button>
      </form>
    </div>
  )
}

export default memo(App)

2.3 使用getFieldProps方法简化表单代码

getFieldProps 方法会帮助我们返回对应表单项input 中的value,onChange 以及onBlur 等属性,放在一个对象中,获取回来后通过{...getFieldProps('xxx')}的形式添加到input 标签中即可,可大大简化我们写form表单的页面代码。

<input
    id='username'
    type='text'
    name='username'
    {...formik.getFieldProps('username')}
    />

完整代码:

import { memo } from 'react'
import { useFormik } from 'formik'
import * as Yup from 'yup'

function App () {
  const formik = useFormik({
    // validateOnChange: false,
    // validateOnBlur: true,
    initialValues: {
      username: '',
      password: ''
    },
    onSubmit: values => {
      console.log(values)
    },
    /* validate: values => {
      const errors = {}
      if (!values.username || values.username.trim() === '') {
        errors.username = '用户名不能为空'
      } else if (values.username.length > 15) {
        errors.username = '用户名长度不能大于15位'
      }

      if (values.password.length < 6) {
        errors.password = '密码长度不能小于6位'
      }
      console.log('validate....', errors)
      return errors
    } */
    // 使用yup 实现验证需要配置 validationSchema, 配置位Yup.object({})所生产的一个对象
    validationSchema: Yup.object({
      username: Yup.string()
        .max(15, '用户名长度不能大于15位')
        .required('请填写用户名'),
      password: Yup.string()
        .min(6, '密码长度不能小于6位')
        .required('请填写密码')
    })
  })
  return (
    <div>
      <form onSubmit={formik.handleSubmit}>
        <div>
          <label htmlFor='username'>用户名</label>
          <input
            id='username'
            type='text'
            name='username'
            {...formik.getFieldProps('username')}
          />
          <p>
            {formik.touched.username && formik.errors.username
              ? formik.errors.username
              : null}
          </p>
        </div>
        <div>
          <label htmlFor='password'>密&nbsp;&nbsp;&nbsp;&nbsp;码</label>
          <input
            id='password'
            type='password'
            name='password'
            {...formik.getFieldProps('password')}
          />
          <p>
            {formik.touched.username && formik.errors.password
              ? formik.errors.password
              : null}
          </p>
        </div>
        <button type='submit'>提交</button>
      </form>
    </div>
  )
}

export default memo(App)

2.4 使用Formik 的组件形式构建表单

好处是可以让我们的表单代码看起来更加简单,它提供了 Formik、Form、Field、ErrorMessage 组件。

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

function App () {
  const initialValues = { username: '', password: '' }
  const handleSubmit = values => {
    console.log(values)
  }
  const validationSchema = Yup.object({
    username: Yup.string()
      .max(15, '用户名长度不能大于15位')
      .required('请填写用户名'),
    password: Yup.string()
      .min(6, '密码长度不能小于6位')
      .required('请填写密码')
  })
  return (
    <Formik
      initialValues={initialValues}
      onSubmit={handleSubmit}
      validationSchema={validationSchema}
    >
      <Form>
        <div>
          <label htmlFor='username'>用户名</label>
          <Field id='username' name='username' />
          <ErrorMessage name='username' />
        </div>
        <div>
          <label htmlFor='password'>密&emsp;码</label>
          <Field id='password' name='password' />
          <ErrorMessage name='password' />
        </div>
        <input type='submit' />
      </Form>
    </Formik>
  )
}

export default memo(App)

2.5 使用 Formik 的组件构建其他表单项

默认情况下,Field 组件渲染的是文本框,如要生成其他表单元素,可以使用如下语法:

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

function App () {
  const initialValues = {
    username: '张三',
    password: '',
    content: '文章整挺好啊',
    subject: 'Java'
  }
  const handleSubmit = values => {
    console.log(values)
  }
  const validationSchema = Yup.object({
    username: Yup.string()
      .max(15, '用户名长度不能大于15位')
      .required('请填写用户名'),
    password: Yup.string()
      .min(6, '密码长度不能小于6位')
      .required('请填写密码')
  })
  return (
    <Formik
      initialValues={initialValues}
      onSubmit={handleSubmit}
      validationSchema={validationSchema}
    >
      <Form>
        <div>
          <label htmlFor='username'>用户名</label>
          <Field id='username' name='username' />
          <ErrorMessage name='username' />
        </div>
        <div>
          <label htmlFor='password'>密&emsp;码</label>
          <Field id='password' type='password' name='password' />
          <ErrorMessage name='password' />
        </div>
        <div>
          <h2>使用Formik的 Field组件 编写其他表单元素</h2>
          <div>
            <label htmlFor='content'>文章内容</label>
            <Field id='content' name='content' as='textarea'></Field>
          </div>
          <div>
            <label htmlFor='content'>文章内容</label>
            <Field id='subject' name='subject' as='select'>
              <option value='前端'>前端</option>
              <option value='Java'>Java</option>
              <option value='Python'>Python</option>
            </Field>
          </div>
        </div>
        <input type='submit' />
      </Form>
    </Formik>
  )
}

export default memo(App)

2.6 使用 useField 构建自定义表单控件

例如单选框,复选框等Formik 是没有给我们提供的,所以需要我们自己去构建这些表单控件。需要用到 useField 方法。自定义表单空间实际上就是组件。

import { memo } from 'react'
import * as Yup from 'yup'
import { Formik, Form, Field, ErrorMessage, useField } from 'formik'
/**
 * 自定义密码表单控件演示案例
 * @param {*} param0
 * @returns
 */
function PasswordInputField ({ label, ...props }) {
  const [field, meta] = useField(props)
  console.log(field, meta)
  return (
    <div>
      <label htmlFor={props.id}>{label}</label>
      <input {...field} {...props} />
      {meta.touched && meta.error ? <span>{meta.error}</span> : null}
    </div>
  )
}

function App () {
  const initialValues = {
    username: '张三',
    password: '',
    password2: 'mymima',
    content: '文章整挺好啊',
    subject: 'Java'
  }
  const handleSubmit = values => {
    console.log(values)
  }
  const validationSchema = Yup.object({
    username: Yup.string()
      .max(15, '用户名长度不能大于15位')
      .required('请填写用户名'),
    password: Yup.string()
      .min(6, '密码长度不能小于6位')
      .required('请填写密码'),
    password2: Yup.string()
      .min(6, '密码2长度不能小于6位')
      .required('请填写密码2')
  })
  return (
    <Formik
      initialValues={initialValues}
      onSubmit={handleSubmit}
      validationSchema={validationSchema}
    >
      <Form>
        <div>
          <label htmlFor='username'>用户名</label>
          <Field id='username' name='username' />
          <ErrorMessage name='username' />
        </div>
        <div>
          <label htmlFor='password'>密&emsp;码</label>
          <Field id='password' type='password' name='password' />
          <ErrorMessage name='password' />
        </div>
        <PasswordInputField
          id='password2'
          type='password'
          name='password2'
          label='密&emsp;码'
          placeholder='请输入密码'
        />
        <div>
          <h2>使用Formik的 Field组件 编写其他表单元素</h2>
          <div>
            <label htmlFor='content'>文章内容</label>
            <Field id='content' name='content' as='textarea'></Field>
          </div>
          <div>
            <label htmlFor='content'>文章内容</label>
            <Field id='subject' name='subject' as='select'>
              <option value='前端'>前端</option>
              <option value='Java'>Java</option>
              <option value='Python'>Python</option>
            </Field>
          </div>
        </div>
        <input type='submit' />
      </Form>
    </Formik>
  )
}

export default memo(App)

2.7 使用 useField 构建自定义表单控件复选框 案例

编写一个复选框控件,让用户可以在一组选项列表中,选择多项内容。

import { memo } from 'react'
import * as Yup from 'yup'
import { Formik, Form, Field, ErrorMessage, useField } from 'formik'

function CheckBox ({ label, ...props }) {
  // useField 返回数组 [FieldInputProps<any>, FieldMetaProps<any>, FieldHelperProps<any>]
  // 其中:FieldHelperProps 是提供给我们对field 的值或改动状态进行修改的方法的
  const [field, meta, helper] = useField(props)

  const { value } = meta
  const { setValue } = helper
  const handleChange = () => {
    // 利用 Set 集合快速去重拷贝数据
    const set = new Set(value)
    if (set.has(props.value)) {
      set.delete(props.value)
    } else {
      set.add(props.value)
    }

    // 对数据进行增删后调用 setValue 更新状态值
    setValue([...set])
  }
  return (
    <div>
      <input
        checked={value.includes(props.value)}
        type='checkbox'
        {...props}
        onChange={handleChange}
      />
      <label htmlFor={props.id}>{label || props.value}</label>
    </div>
  )
}

function MultipleSelectField ({ label, options = [], ...props }) {
  const [field, meta] = useField(props)
  return (
    <div>
      {label ? <label htmlFor={props.id}>{label}</label> : null}
      <select multiple {...field} {...props}>
        <option disabled>请选择</option>
        {options.map(option => {
          return (
            <option key={option.name || option} value={option.value || option}>
              {option.name || option.value || option}
            </option>
          )
        })}
      </select>
      {meta.touched && meta.error ? <span>{meta.error}</span> : null}
    </div>
  )
}

/**
 * 自定义密码表单控件演示案例
 * @param {*} param0
 * @returns
 */
function PasswordInputField ({ label, ...props }) {
  const [field, meta] = useField(props)
  return (
    <div>
      {label ? <label htmlFor={props.id}>{label}</label> : null}
      <input {...field} {...props} />
      {meta.touched && meta.error ? <span>{meta.error}</span> : null}
    </div>
  )
}

function App () {
  const initialValues = {
    username: '张三',
    password: '',
    password2: 'mymima',
    content: '文章整挺好啊',
    subject: 'Java',
    hobbies: ['吃饭', '睡觉'],
    careers: ['前端开发']
  }
  const handleSubmit = values => {
    console.log(values)
  }
  const validationSchema = Yup.object({
    username: Yup.string()
      .max(15, '用户名长度不能大于15位')
      .required('请填写用户名'),
    password: Yup.string()
      .min(6, '密码长度不能小于6位')
      .required('请填写密码'),
    password2: Yup.string()
      .min(6, '密码2长度不能小于6位')
      .required('请填写密码2'),
    hobbies: Yup.array()
      .min(1, '必须发展一个爱好')
      .max(2, '最多发展2个爱好')
  })
  return (
    <Formik
      initialValues={initialValues}
      onSubmit={handleSubmit}
      validationSchema={validationSchema}
    >
      <Form>
        <div>
          <label htmlFor='username'>用户名</label>
          <Field id='username' name='username' />
          <ErrorMessage name='username' />
        </div>
        <div>
          <label htmlFor='password'>密&emsp;码</label>
          <Field id='password' type='password' name='password' />
          <ErrorMessage name='password' />
        </div>
        <p>自定义的表单控件</p>
        <PasswordInputField
          id='password2'
          type='password'
          name='password2'
          label='密&emsp;码'
          placeholder='请输入密码'
        />
        <MultipleSelectField
          id='hobbies'
          type='select'
          name='hobbies'
          label='爱&emsp;好'
          placeholder='请选择爱好'
          options={['吃饭', '睡觉', '打豆豆']}
        />
        <h3>职&emsp;业</h3>
        <CheckBox id='前端开发xxx' value='前端开发' name='careers' />
        <CheckBox id='Java开发xxx' value='Java开发' name='careers' />
        <CheckBox id='全栈开发xxx' value='全栈开发' name='careers' />
        <div>
          <h2>使用Formik的 Field组件 编写其他表单元素</h2>
          <div>
            <label htmlFor='content'>文章内容</label>
            <Field id='content' name='content' as='textarea'></Field>
          </div>
          <div>
            <label htmlFor='content'>文章内容</label>
            <Field id='subject' name='subject' as='select'>
              <option value='前端'>前端</option>
              <option value='Java'>Java</option>
              <option value='Python'>Python</option>
            </Field>
          </div>
        </div>
        <input type='submit' />
      </Form>
    </Formik>
  )
}

export default memo(App)

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抱歉,我作为语言模型无法直接提供源代码。但是,我可以为您提供一些指导和资源,以帮助您开始使用React构建后台管理系统。 1. 学习React基础知识 在开始构建React应用程序之前,您需要了解React的基础知识,例如组件、状态和属性。以下是一些有用的资源: - React官方文档:https://reactjs.org/docs/getting-started.html - React教程:https://reactjs.org/tutorial/tutorial.html - React Hooks文档:https://reactjs.org/docs/hooks-intro.html 2. 选择UI框架 React并不是一个完整的UI框架,它只是一个构建用户界面的库。因此,您需要选择一个UI框架来帮助您构建漂亮的界面。以下是一些最受欢迎的React UI框架: - Ant Design:https://ant.design/ - Material-UI:https://material-ui.com/ - Bootstrap:https://getbootstrap.com/ - Semantic UI:https://semantic-ui.com/ 3. 搭建React开发环境 在开始编写React代码之前,您需要搭建React开发环境。以下是一些最常用的工具: - Node.js:https://nodejs.org/ - Create React App:https://create-react-app.dev/ 4. 编写后台管理系统代码 一旦您了解了React基础知识、选择了一个UI框架并搭建了React开发环境,您就可以开始编写后台管理系统代码了。以下是一些常见的功能: - 路由:使用React Router来创建路由,使用户能够在应用程序中导航。 - 表单:使用React表单库,例如Formik或React Hook Form,来管理表单数据。 - 状态管理:使用React的Context API或Redux来管理应用程序状态。 - 数据表格:使用React表格库,例如React Table或Material Table,来显示和操作数据。 注意:React是一个非常灵活的库,您可以使用许多不同的方法来实现相同的功能。因此,您可以根据自己的需求和喜好来编写代码。 希望这些资源和指导能够帮助您开始使用React构建后台管理系统。祝您好运!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值