redux-form的学习笔记二--实现表单的同步验证

:这篇博客参考自redux-form的官方英文文档)左转http://redux-form.com/6.5.0/examples/syncValidation/

在这篇博客里,我将用redux-form实现一个同步验证的表单,它将满足以下条件:

1有三个输入框:用户名输入框(username),邮箱输入框(email)和年龄输入框(age)

2如果点击输入框获取焦点后未输入内容,则在输入框失去焦点后发出错误(error)提示:XXX不能为空,且此时不能提交成功

3如果在输入框中输入内容不合法,比如用户名过长(length>5)发出错误提示:不能大于五个字,且此时不能提交成功

4如果在输入框中输入内容合法但需警告,则提示警告(warn)内容,此时虽然发出警告但仍能提交成功(请区分和2和3中的区别)

5在尚未输入内容时(pristine=true)或在提交过程中(submitting=true),禁止使用提交按钮。在点击清空按钮时,调用reset()方法清空所有输入框中的内容

首先附上form.js的代码:(这份展示一共两份代码:index.js和form.js,index.js的内容请看上一篇博客)

import React from 'react'
import { Field, reduxForm } from 'redux-form'

const validate = values => {
  const errors = {}
  if (!values.username) {
    errors.username = '用户名不能为空'
  } else if (values.username.length > 5) {
    errors.username = '不能大于五个字'
  }
  if (!values.email) {
    errors.email = '邮箱不能为空'
  } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
    errors.email = 'Invalid email address'
  }
  if (!values.age) {
    errors.age = '年龄不能为空'
  } else if (isNaN(Number(values.age))) {
    errors.age = '年龄必须是一个数字'
  } else if (Number(values.age) < 18) {
    errors.age = '对不起,你未满18岁'
  }
  return errors
}

const warn = values => {
  const warnings = {}
  if (values.age < 19) {
    warnings.age = '你年龄还有点小哦!'
  }
  return warnings
}

const renderField = ({ input, label, type, meta: { touched, error, warning } }) => (
  <div>
    <label>{label}</label>
    <div>
      <input {...input} placeholder={label} type={type}/>
      {touched && ((error && <span>{error}</span>) || (warning && <span>{warning}</span>))}
    </div>
  </div>
)

const SyncValidationForm = (props) => {
  const { handleSubmit, pristine, reset, submitting } = props
  return (
    <form onSubmit={handleSubmit}>
      <Field name="username" type="text" component={renderField} label="Username"/>
      <Field name="email" type="email" component={renderField} label="Email"/>
      <Field name="age" type="number" component={renderField} label="Age"/>
      <div>
        <button type="submit" disabled={submitting}>Submit</button>
        <button type="button" disabled={pristine || submitting} onClick={reset}>Clear Values</button>
      </div>
    </form>
  )
}
export default reduxForm({
  form: 'syncValidation',  //你的redux-form的特殊标记,必填项
  validate,                // 上面定义的一个验证函数,使redux-form同步验证
  warn                     // 上面定义的一个错误提示函数,使redux-form同步错误提示
})(SyncValidationForm)//写入的redux-form组件

1什么是Field组件?

Field组件是redux-form组件库中的核心组件,它位于你的输入框(input)或输入框组件的外一层,将其包装起来从而使输入框能和redux的store直接连接起来。

它有两个最重要的属性:name属性和component属性,且这两个属性都是必填项 

<Field name="username" type="text" component={renderField} label="Username"/>

在上面的Field中name和component是必填的,而type属性和label属性是选填的,但选填的属性(如type和label)可通过props属性传入它的component中,比如以上的renderField中

2Field组件的name属性和component属性

  • name属性是Filed组件的名称,也即Field下输入框的名称,它将成为存储form表单数据的values对象中的属性名:比如?的SyncValidationForm的values对象在输入后是这样的:
{
username:彭湖湾,
email:2314838003@qq.com,
age:20
}
  • component属性的值是Field包裹的input组件,它可有三种形式:

1纯字符串如inputtextarea 或者 select:

<Field name="username" component="input" />

2组件名称:通过class定义的组件或者无状态函数组件(stateless function)

<1>class定义

class MyInput extends Component {
  render() {
   .......
  }
}
<Field name="myField" component={MyInput}/>

<2>无状态函数组件:

const  Myinput = (props) => {
  return (<input ... />)
}
<Field name="myField" component={MyInput}/>

注意!:只要写函数名即可,不要写html的格式,要写成component={Myinput}而不是component={<Myinput />}!

3reduxForm(...)(yourForm)有何作用?

熟悉redux数据流的同学应该对这个函数很熟悉吧,没错,它和redux的connect(...)(...)函数非常类似,通过

reduxForm({
  form: 'syncValidation',  //你的redux-form的特殊标记,必填项
  validate,                // 一个验证函数,使redux-form同步验证
  warn                     // 一个错误提示函数,使redux-form同步错误提示
})(SyncValidationForm)//写入的redux-form组件

(这里的validate和warn采用了ES6的对象属性的简化写入写法,相当于validate:validate和warn:warn)

一方面实现了对使redux-form实现了同步验证等功能,同时还将handleSubmit等自带的属性以props的形式传入SyncValidationForm中,使他“增强”了,是不是和connect(...)(...)很相似呢?然后通过

const SyncValidationForm = (props) => {
  const { handleSubmit, pristine, reset, submitting } = props
    .....       
}

你就在SyncValidationForm中取到了这些属性值

关于handleSubmit,pristine,reset和submitting的作用我这里简单介绍一下,详细的大家可以去看英文的API:左转http://redux-form.com/6.5.0/docs/api/Props.md/

  • handleSubmit是处理提交的一个函数,接收三个参数:values(即上文提到的保存表单数据的对象),dispatch和props(传递给自定义表单组件的属性)
  • pristine是一个布尔型的值,如果表单初始化后尚未输入值,为true,否则为false,当你向表单中第一个输入框中输入值的时候,pristine就由true转为false了
  • reset是一个函数,调用reset()可清空表单
  • submitting是一个布尔型数值,true表示表单正在提交

 运行结果如下:

1--验证是否为空

2--验证是否满足格式

3

4

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏xingoo, 一个梦想做发明家的程序员

Kibana源码剖析 —— savedSearch从读取到跳转

持久化对象 Kibana中可以查询到很多保存的对象,他们都存储在es中一个叫做.kibana的索引中。 搜索 存储在type为search中; 图表 存储在ty...

1928
来自专栏郭少华

(第二季)Vue2.0-全局API

全局API并不在构造器里,而是先声明全局变量或者直接在Vue上定义一些新功能,Vue内置了一些全局API,说的简单些就是,在构造器外部用Vue提供给我们的API...

471
来自专栏柠檬先生

jquery 表单事件

.blur()    当元素失去焦点的时候触发事件。   .blur(handler(eventObject))     handler(even...

1739
来自专栏Youngxj

解决Emlog博客程序伪静态后URL不是唯一地址的教程

1884
来自专栏向治洪

用xml来编写动画

我们可以使用代码来编写所有的动画功能,这也是最常用的一种做法。不过,过去的补间动画除了使用代码编写之外也是可以使用XML编写的,因此属性动画也提供了这一功能,...

1775
来自专栏青玉伏案

JavaEE开发之Spring中Bean的作用域、Init和Destroy方法以及Spring-EL表达式

上篇博客我们聊了《JavaEE开发之Spring中的依赖注入以及AOP》,本篇博客我们就来聊一下Spring框架中的Bean的作用域以及Bean的Init和De...

1947
来自专栏Crossin的编程教室

在 Win 控制台中实现菜单

本教室的 hymyg 同学实现了两个控制台下的实用模块,发在了论坛上。我觉得挺不错的,于是分享其中的一个给大家。对项目感兴趣,想进一步了解细节的,可以在公众号里...

2635
来自专栏对角另一面

lodash源码分析之缓存方式的选择

每个人心里都有一团火,路过的人只看到烟。 ——《至爱梵高·星空之谜》 本文为读 lodash 源码的第八篇,后续文章会更新到这个仓库中,欢迎 star:po...

3179
来自专栏守望轩

Visual Studio 2008 每日提示(八)

#071、给所有快速查询的结果标记上书签 原文链接:Did you know… You can bookmark all of your Quick Find...

2645
来自专栏程序你好

1000个项目中前10名的JavaScript错误介绍

421

扫码关注云+社区