使用Formik轻松开发更高质量的React表单(二)使用指南

一个基本的例子

设想你要开发一个可以编辑用户数据的表单。不过,你的用户API端使用了具有类似下面的嵌套对象表达:

从网站建设到定制行业解决方案,为提供成都网站制作、网站建设、外贸网站建设服务体系,各种行业企业客户提供网站建设解决方案,助力业务快速发展。创新互联将不断加快创新步伐,提供优质的建站服务。

{
   id: string,
   email: string,
   social: {
     facebook: string,
     twitter: string,
     // ...
   }
}

最后,我们想使开发的对话框表单能够接收下面几个属性(props):user,updateUser和onClose(显然,user是一个对象,updateUser和onClose却都是两个方法)。

// User.js
import React from 'react';
import Dialog from 'MySuperDialog';
import { Formik } from 'formik';

const EditUserDialog = ({ user, updateUser, onClose }) => {
  return (
    
      

Edit User

{ CallMyApi(user.id, values).then( updatedUser => { actions.setSubmitting(false); updateUser(updatedUser), onClose(); }, error => { actions.setSubmitting(false); actions.setErrors(transformMyAPIErrorToAnObject(error)); } ); }} render={({ values, errors, touched, handleBlur, handleChange, handleSubmit, isSubmitting, }) => (
{errors.email && touched.email &&
{errors.email}
} {errors.social && errors.social.facebook && touched.facebook &&
{errors.social.facebook}
} {errors.social && errors.social.twitter && touched.twitter &&
{errors.social.twitter}
}
)} />
); };

简化编码

为了简化表单组件的编码,Formik还提供了两个帮助API:



于是,下面的代码与前面一致,只是使用和这两个API进行了改写:

// EditUserDialog.js
import React from 'react';
import Dialog from 'MySuperDialog';
import { Formik, Field, Form } from 'formik';

const EditUserDialog = ({ user, updateUser, onClose }) => {
  return (
    
      

Edit User

{ CallMyApi(user.id, values).then( updatedUser => { actions.setSubmitting(false); updateUser(updatedUser), onClose(); }, error => { actions.setSubmitting(false); actions.setErrors(transformMyAPIErrorToAnObject(error)); } ); }} render={({ errors, touched, isSubmitting }) => ( {errors.email && touched.social.email &&
{errors.email}
} {errors.social.facebook && touched.social.facebook &&
{errors.social.facebook}
} {errors.social.twitter && touched.social.twitter &&
{errors.social.twitter}
} )} />
); };

React Native开发问题


Formik与React Native 和React Native Web开发完全兼容。然而,由于ReactDOM和React Native表单处理与文本输入方式的不同,有两个区别值得注意。本文将介绍这个问题并推荐更佳使用方式。

在进一步讨论前,先来最简要地概括一下如何在React Native中使用Formik。下面的轮廓代码展示了两者的关键区别:

// Formik +React Native示例
import React from 'react';
import { Button, TextInput, View } from 'react-native';
import { withFormik } from 'formik';

const enhancer = withFormik({
  /*...*/
});

const MyReactNativeForm = props => (
  
    
    

从上面代码中,你会明显注意到在React Native 和React DOM开发中使用Formik存在如下不同:


(1)Formik的props.handleSubmit被传递给一个 ); }; //MyForm接收的props的类型 interface MyFormProps { initialEmail?: string; message: string; // if this passed all the way through you might do this or make a union type } //使用withFormik高阶组件包装你的表单 const MyForm = withFormik({ // Transform outer props into form values mapPropsToValues: props => { return { email: props.initialEmail || '', password: '', }; }, //添加定制的校验函数(也有可能是异步的) validate: (values: FormValues) => { let errors: FormikErrors = {}; if (!values.email) { errors.email = 'Required'; } else if (!isValidEmail(values.email)) { errors.email = 'Invalid email address'; } return errors; }, handleSubmit: values => { // do submitting things }, })(InnerForm); // 你可以在任何地方使用 const Basic = () => (

My App

This can be anywhere in your application

); export default Basic;

Formik表单提交原理


要在Formik中提交表单,你需要以某种方式触发 handleSubmit(e) 或者submitForm属性调用(在Formik中这两个方法都是以属性的方式提供的)。 当调用其中一个方法时,Formik每次都会执行下面的伪代码:

(一)预提交
(1)修改所有字段
(2)把isSubmitting 设置为true
(3)submitCount + 1
(二)校验
(1)把isValidating设置为true
(2)异步运行所有字段级的校验和validationSchema,并深度合并执行结果
(3)判断是否存在错误:
如果存在错误:取消提交,把isValidating设置为false,设置错误信息,并把isSubmitting设置为false
如果不存在错误:Set isValidating to false, proceed to "Submission"
(三)提交
最后继续运行你的提交函数吧(例如是onSubmit或者handleSubmit)。你可以通过在你的处理器函数中调用setSubmitting(false) 来结束生命周期。

FAQ



(1)Q:怎么判定提交处理器(submission handler)正在执行中?
A:当isValidating为false且isSubmitting为true时。

(2)Q:为什么在提交前Formik要“润色一下(touch)”表单中所有字段?
A:通常,当UI表单中输入字段被操作过后(Formik中称为“touched”)只显示与之相关的错误信息。于是,在提交一个表单前,Formik会touch一下所有字段,这样所有可能隐藏的错误都会变得可见。

(3)Q:如何避免两次重复提交?
A:办法是当isSubmitting为true时,禁止所有能够触发提交的调用。

(4)Q:如何得知表单在提交前正在校验中?
A:如果isValidating为true而且isSubmitting也为true的话,......


分享标题:使用Formik轻松开发更高质量的React表单(二)使用指南
浏览地址:http://scyanting.com/article/ghssdi.html