07- react中表单校验

78 阅读2分钟

一、formik表单处理

1. 安装

yarn add formik

2 导入 withFormik

class Login extends Component {
  render() {
    // 通过 props 获取高阶组件传递进来的属性
    const { values: { username, password }, handleSubmit, handleChange } = this.props

    return (
      <div>
        {/* 登录表单 */}
          <form onSubmit={handleSubmit}>
              <input
                value={username}
                onChange={handleChange}
                name="username"
                placeholder="请输入账号"
              />

              <input
                value={password}
                onChange={handleChange}
                name="password"
                type="password"
                placeholder="请输入密码"
              />
            <div>
              <button type="submit">
                登 录
              </button>
            </div>
          </form>
      </div>
    )
  }
}

// 使用 withFormik 高阶组件包装 Login 组件,为 Login 组件提供属性和方法
Login = withFormik({
  // 提供状态:
  mapPropsToValues: () => ({ username: '', password: '' }),
  // 表单的提交事件
  handleSubmit: async (values, { props }) => {
  // .....提交逻辑.....
  }
})(Login)

// 注意:此处返回的是 高阶组件 包装后的组件
export default Login

3. 给登录功能添加表单验证

  • 安装: yarn add yup (Yup 文档),导入Yup

导入Yup

// 导入Yup
import * as Yup from 'yup'
// 验证规则:
const REG_UNAME = /^[a-zA-Z_\d]{5,8}$/
const REG_PWD = /^[a-zA-Z_\d]{5,12}$/

class Login extends Component {
  render() {
    // 通过 props 获取高阶组件传递进来的属性
    const { values: { username, password },
           handleSubmit,
           handleChange, 
           // 失去焦点的默认处理
           handleBlur,
           // 触发校验时的错误信息
      		 errors,
           // 触发哪一项表单校验
      		 touched } = this.props

    return (
      <div>
        {/* 登录表单 */}
          <form onSubmit={handleSubmit}>
              <input
                value={username}
                onChange={handleChange}
                onBlur={handleBlur}
                name="username"
                placeholder="请输入账号"
              />
            {/* 错误信息提示 */}
						{errors.username && touched.username && (
              <div className={styles.error}>{errors.username}</div>
            )}
              <input
                value={password}
                onChange={handleChange}
                onBlur={handleBlur}
                name="password"
                type="password"
                placeholder="请输入密码"
              />
            {/* 错误信息提示 */}
            {errors.password && touched.password && (
              <div className={styles.error}>{errors.password}</div>
            )}
            <div>
              <button type="submit">
                登 录
              </button>
            </div>
          </form>
      </div>
    )
  }
}

Login = withFormik({
  // 提供状态:
  mapPropsToValues: () => ({ username: '', password: '' }),
  // 表单的提交事件
  handleSubmit: async (values, { props }) => {
  // .....提交逻辑.....
  }
  // 添加表单校验规则
  validationSchema: Yup.object().shape({
    username: Yup.string()
      .required('账号为必填项')
      .matches(REG_UNAME, '长度为5到8位,只能出现数字、字母、下划线'),
    password: Yup.string()
      .required('密码为必填项')
      .matches(REG_PWD, '长度为5到12位,只能出现数字、字母、下划线')
  })
})(Login)

4、简化上面代码

// 导入Yup
import * as Yup from 'yup'

// 导入withFormik
import { withFormik, Form, Field, ErrorMessage } from 'formik'

// 验证规则:
const REG_UNAME = /^[a-zA-Z_\d]{5,8}$/
const REG_PWD = /^[a-zA-Z_\d]{5,12}$/

class Login extends Component {
  render() {
    // 通过 props 获取高阶组件传递进来的属性
    const { values: { username, password },
           handleSubmit,
           handleChange, 
           // 失去焦点的默认处理
           handleBlur,
           // 触发校验时的错误信息
      		 errors,
           // 触发哪一项表单校验
      		 touched } = this.props

    return (
      <div>
        {/* 登录表单 */}
          <Form>
              <Field
                name="username"
                placeholder="请输入账号"
              />
            {/* 错误信息提示 */}
							<ErrorMessage
           	   name="username"
           	   component="div"
           		 />
              <Field
                name="password"
                type="password"
                placeholder="请输入密码"
              />
            {/* 错误信息提示 */}
            	<ErrorMessage
              	name="password"
              	component="div"
            	/>
            <div>
              <button type="submit">
                登 录
              </button>
            </div>
          </Form>
      </div>
    )
  }
}

Login = withFormik({
  // 提供状态:
  mapPropsToValues: () => ({ username: '', password: '' }),
  // 表单的提交事件
  handleSubmit: async (values, { props }) => {
  // .....提交逻辑.....
  }
  // 添加表单校验规则
  validationSchema: Yup.object().shape({
    username: Yup.string()
      .required('账号为必填项')
      .matches(REG_UNAME, '长度为5到8位,只能出现数字、字母、下划线'),
    password: Yup.string()
      .required('密码为必填项')
      .matches(REG_PWD, '长度为5到12位,只能出现数字、字母、下划线')
  })
})(Login)