Formik-Getting Started2020-05-27 22:57Dev, React, Form, Formik

Formik-Getting Started

Formik: V2.1.4

React. Children.only expected to receive a single React element child

<Formik> 理论上接收一个 Child

里面一般是一个函数回调

而不是直接将一堆 component 扔到 <Formik> 里面

formik.values.xxx, Object is of type 'unknown'

如果获取 formik 的时候没有设置 Generic Type 就会出现这样的错误

添加上 Type 即可

const formikBag = useFormikContext<CustomFormType>();

或者

<Formik>
  (formikBag: FormikProps<CustomFormType>) => {

  }
</Formik>

formik.values doesn't changed when initialValue changed

重设 initialValue 的时候 formik.values 没有更新

经常是因为 Hooks 改变了 initialValues

<Formik
    initialValues={initialValues}
    onSubmit={submitForm}
    enableReinitialize={true}  // enableReinitialize default to FALSE, set it to TRUE
    validateOnMount={false}
    validationSchema={validationSchema}
>

Trigger Validation Only

表单的 validatio 可以单独 trigger

formik.validateForm()

formik.handleSubmit()

Field Level Validation

import React from 'react';
import {Formik, Form, Field} from 'formik';

/* Validate 方法, 返回 undefined 代表没有 Error */
function validateEmail(value) {
  let error;
  if (!value) {
    error = 'Required';
  } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value)) {
    error = 'Invalid email address';
  }
  return error;
}

function validateUsername(value) {
  let error;
  if (value === 'admin') {
    error = 'Nice try!';
  }
  return error;
}

export const FieldLevelValidationExample = () => (
  <div>
    <h1>Signup</h1>
    <Formik
      initialValues={{
        username: '',
        email: '',
      }}
      onSubmit={values => {
        // same shape as initial values
        console.log(values);
      }}
    >
      {({errors, touched, validateField, validateForm}) => (
        <Form>
          {/** 单个 field, 设置 validate 方法并且通过 errors 获得到 error 内容 */}
          <Field name="email" validate={validateEmail} />
          {errors.email && touched.email && <div>{errors.email}</div>}

          {/** 同上 */}
          <Field name="username" validate={validateUsername} />
          {errors.username && touched.username && <div>{errors.username}</div>}

          {/** Trigger FIELD-LEVEL validation imperatively */}
          <button type="button" onClick={() => validateField('username')}>
            Check Username
          </button>

          {/** Trigger FORM-LEVEL validation imperatively */}
          <button type="button" onClick={() => validateForm().then(() => console.log('blah')))}>
            Validate All
          </button>

          <button type="submit">Submit</button>
        </Form>
      )}
    </Formik>
  </div>
);

Different ways to get Formik

useFormik()

可以通过 formik hook 来进行各种设置和操作

 import React from 'react';
 import {useFormik} from 'formik';

 const SignupForm = () => {
   const formik = useFormik({
     initialValues: {
       firstName: '',
       lastName: '',
       email: '',
     },
     onSubmit: values => {
       alert(JSON.stringify(values, null, 2));
     },
   });
   return (
     <form onSubmit={formik.handleSubmit}>
       {......}
     </form>
   );
 };

<Formik />

这个很麻烦, 如果要操作 form 那么就需要到

 import React from 'react';
 import {Formik} from 'formik';

 const BasicExample = () => (
   <div>
     <h1>My Form</h1>
     <Formik
       initialValues={{name: 'jared'}}
       onSubmit={(values, actions) => {
         setTimeout(() => {
           alert(JSON.stringify(values, null, 2));
           actions.setSubmitting(false);
         }, 1000);
       }}
     >
       {props => {
        //  从这里可以通过 useFormikContext() 来获取 formik
        return (
         <form onSubmit={props.handleSubmit}>
           <input
             type="text"
             onChange={props.handleChange}
             onBlur={props.handleBlur}
             value={props.values.name}
             name="name"
           />
           {props.errors.name && <div id="feedback">{props.errors.name}</div>}
           <button type="submit">Submit</button>
         </form>
        )}
       }
     </Formik>
   </div>
 );

useFormikContext()

见上方代码, 只有在 Formik 元素里面 (通过 <Formik> 标签或者 withFormik() 包裹的内容里面) 才会有这一段上下文, 才能使用这个函数

Powered by Remix
|
Designed by szhshp
|
Copyright © szhshp 2022