{"id":1405,"date":"2020-08-14T16:39:41","date_gmt":"2020-08-14T16:39:41","guid":{"rendered":"https:\/\/lvboard.infostore.in.ua\/?p=1405"},"modified":"2020-08-14T16:39:41","modified_gmt":"2020-08-14T16:39:41","slug":"the-ultimate-roundup-of-react-form-validation-solutions","status":"publish","type":"post","link":"https:\/\/lvboard.infostore.in.ua\/?p=1405","title":{"rendered":"The ultimate roundup of React form validation solutions"},"content":{"rendered":"\n<p>As a developer, it\u2019s usually best to not reinvent the wheel. That\u2019s why the first step for implementing a solution is to look for existing solutions. And it\u2019s what React is all about \u2014 creating reusable components so we don\u2019t end up repeating ourselves.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>In this article, we\u2019re going to take a look at some of the most popular solutions for form management and validation in React.<\/p>\n\n\n\n<h2><a href=\"https:\/\/jaredpalmer.com\/formik\/\" target=\"_blank\" rel=\"noreferrer noopener\">Formik<\/a><\/h2>\n\n\n\n<p>A roundup on React form solutions wouldn\u2019t be complete without Formik. With over&nbsp;<a href=\"https:\/\/github.com\/jaredpalmer\/formik\" target=\"_blank\" rel=\"noreferrer noopener\">22k stars on GitHub<\/a>, it is basically the most popular library for building and managing forms in React. Formik is a scalable, performant, form helper with a minimal API. It handles form state management, validation, and error handling.<\/p>\n\n\n\n<h3>Installation<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">yarn add formik<\/pre>\n\n\n\n<h3>Basic usage<\/h3>\n\n\n\n<p>Here\u2019s how to use Formik in it\u2019s most basic form. The&nbsp;<code>useFormik<\/code>&nbsp;Hook is where all the goodness is encapsulated. To use it, it only requires you to pass in the&nbsp;<code>initialValues<\/code>&nbsp;which is an object containing the default values of each of your form fields. And the&nbsp;<code>onSubmit<\/code>&nbsp;handler which gets called when the form validation passes.<\/p>\n\n\n\n<p>When&nbsp;<code>useFormik<\/code>&nbsp;is called, it returns the event handlers and form state which we could use to specify when to trigger form validation. The validation rules are added through the&nbsp;<code>validate<\/code>&nbsp;property. A callback function is passed as the value for this property. And it\u2019s where you validate the individual form fields. The validation gets triggered on the&nbsp;<code>onChange<\/code>&nbsp;event of every field. This means that by default, when the user updates the value for the first field, all the other fields in the form will have its validation code get triggered as well. We don\u2019t really want that, that\u2019s why we need to extract the&nbsp;<code>handleBlur<\/code>&nbsp;and&nbsp;<code>touched<\/code>&nbsp;from the return object of&nbsp;<code>useFormik<\/code>. The former allows us to listen for blur events from the fields, while the latter allows us to check whether the user has already visited the field. From there, we can just check for the errors through the&nbsp;<code>errors<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import React from \"react\";\nimport { useFormik } from \"formik\";\n\nfunction FormikComponent() {\n  function validate(values) {\n    const errors = {};\n    if (!values.favoriteFood) {\n      errors.favoriteFood = \"Required\";\n    }\n\n    if (!values.favoritePlace) {\n      errors.favoritePlace = \"Required\";\n    }\n    return errors;\n  }\n\n  const {\n    handleSubmit,\n    handleChange,\n    handleBlur,\n    touched,\n    values, \/\/ use this if you want controlled components\n    errors,\n  } = useFormik({\n    initialValues: {\n      favoriteFood: \"\",\n      favoritePlace: \"\",\n    },\n    validate,\n    onSubmit: (values) =&gt; {\n      console.log(JSON.stringify(values));\n      \/\/ values = {\"favoriteFood\":\"ramen\",\"favoritePlace\":\"mountains\"}\n    },\n  });\n\n  return (\n    &lt;form onSubmit={handleSubmit}&gt;\n      &lt;label htmlFor=\"favoriteFood\"&gt;Favorite Food:&lt;\/label&gt;\n      &lt;input\n        type=\"text\"\n        name=\"favoriteFood\"\n        onChange={handleChange}\n        onBlur={handleBlur}\n      \/&gt;\n      {touched.favoriteFood &amp;&amp; errors.favoriteFood\n        ? &lt;div&gt;errors.favoriteFood&lt;\/div&gt;\n        : null}\n\n      &lt;label htmlFor=\"favoritePlace\"&gt;Favorite place:&lt;label&gt;\n      &lt;input\n        type=\"text\"\n        name=\"favoritePlace\"\n        onChange={handleChange}\n        onBlur={handleBlur}\n      \/&gt;\n\n      {touched.favoritePlace &amp;&amp; errors.favoritePlace\n        ? &lt;div&gt;errors.favoritePlace&lt;\/div&gt;\n        : null}\n\n      &lt;button type=\"submit\"&gt;submit&lt;\/button&gt;\n    &lt;\/form&gt;    \n  );\n}\n\nexport default App;<\/pre>\n\n\n\n<p>The above example is nice, but it can get out of hand quickly on more complex forms. For that, we could use the&nbsp;<a href=\"https:\/\/github.com\/jquense\/yup\" target=\"_blank\" rel=\"noreferrer noopener\">Yup<\/a>&nbsp;library. Yup is a schema builder for parsing values and validating them. You can install it with the following command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">yarn add yup<\/pre>\n\n\n\n<p>To use Yup, all you have to do is replace&nbsp;<code>validate<\/code>&nbsp;with&nbsp;<code>validationSchema<\/code>. This is specifically created for Yup integration:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import * as Yup from \"yup\";\n\nfunction App() {\n  const schema = Yup.object({\n    favoriteFood: Yup.string().required(\"Required\"),\n    favoritePlace: Yup.string().required(\"Required\"),\n  });\n\n  const { ... } = useFormik = ({\n    \/\/ ...\n    validationSchema: schema \/\/ replace validate with this\n  });\n}<\/pre>\n\n\n\n<h3>Summary<\/h3>\n\n\n\n<ul><li>Supports schema-based form validation through the Yup library<\/li><li>Does not use external state management libraries like Redux to manage form state<\/li><li><a href=\"https:\/\/jaredpalmer.com\/formik\/docs\/guides\/react-native\" target=\"_blank\" rel=\"noreferrer noopener\">Compatible with both React Native and React Native Web<\/a><\/li><li><a href=\"https:\/\/bundlephobia.com\/result?p=formik@2.1.4\" target=\"_blank\" rel=\"noreferrer noopener\">Weighs 15Kb<\/a>&nbsp;when minified then gzipped<\/li><\/ul>\n\n\n\n<h2><a href=\"https:\/\/final-form.org\/react\" target=\"_blank\" rel=\"noreferrer noopener\">React Final Form<\/a><\/h2>\n\n\n\n<p>React Final Form is framework-agnostic form validation library with zero dependencies.&nbsp;<a href=\"https:\/\/github.com\/final-form\/final-form\" target=\"_blank\" rel=\"noreferrer noopener\">Final Form<\/a>&nbsp;is the name of the actual library, while React Final Form is the React wrapper. It is subscription-based, so only the specific form fields will get updated when the form state is updated.<\/p>\n\n\n\n<h3>Installation<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">yarn add final-form react-final-form<\/pre>\n\n\n\n<h3>Basic usage<\/h3>\n\n\n\n<p>There are two ways of validating forms with React Final Form \u2014&nbsp;<a href=\"https:\/\/final-form.org\/docs\/react-final-form\/examples\/record-level-validation\" target=\"_blank\" rel=\"noreferrer noopener\">record-level<\/a>&nbsp;and&nbsp;<a href=\"https:\/\/final-form.org\/docs\/react-final-form\/examples\/field-level-validation\" target=\"_blank\" rel=\"noreferrer noopener\">field-level<\/a>. Record level is pretty much the same as how it\u2019s done with Formik. And just like Formik, you can also easily use Yup for implementing validation rules. The way you validate your form depends on how complex your form is. If your form is fairly simple, you can stick with field-level validation. Otherwise, use record-level.<\/p>\n\n\n\n<p>Here\u2019s an example of record-level validation using Yup. This requires us to use the&nbsp;<code>setIn<\/code>&nbsp;utility function from the Final Form library to transform the default error object into an object which uses dot-and-bracket syntax (e.g.&nbsp;<code>people[0].name.first<\/code>). In the code below, you can see that the way it works is similar to Formik. Though it relies on the use of custom components (<code>&lt;Form&gt;<\/code>&nbsp;and&nbsp;<code>&lt;Field&gt;<\/code>&nbsp;to wrap the primitive HTML elements to provide it with state and input callbacks:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import React from \"react\";\nimport { setIn } from \"final-form\";\nimport { Form, Field } from \"react-final-form\";\nimport * as Yup from \"yup\";\n\nconst schema = Yup.object({\n  favoriteFood: Yup.string().required(\"Required\"),\n});\n\nconst validate = async (values) =&gt; {\n  try {\n    await schema.validate(values, { abortEarly: false });\n  } catch (err) {\n    const errors = err.inner.reduce((formError, innerError) =&gt; {\n      return setIn(formError, innerError.path, innerError.message);\n    }, {});\n\n    return errors;\n  }\n};\n\nconst onSubmit = (values) =&gt; {\n  console.log(\"values: \", values);\n};\n\nfunction FinalFormComponent() {\n  return (\n    &lt;Form\n      onSubmit={onSubmit}\n      validate={validate}\n      render={({ handleSubmit, form, submitting, pristine, values }) =&gt; (\n        &lt;form onSubmit={handleSubmit}&gt;\n          &lt;Field name=\"favoriteFood\"&gt;\n            {({ input, meta }) =&gt; (\n              &lt;div&gt;\n                &lt;label&gt;Favorite Food&lt;\/label&gt;\n                &lt;input {...input} type=\"text\" placeholder=\"favoriteFood\" \/&gt;\n                {meta.error &amp;&amp; meta.touched &amp;&amp; &lt;span&gt;{meta.error}&lt;\/span&gt;}\n              &lt;\/div&gt;\n            )}\n          &lt;\/Field&gt;\n          &lt;button type=\"submit\"&gt;submit&lt;\/button&gt;\n        &lt;\/form&gt;\n      )}\n    \/&gt;\n  );\n}<\/pre>\n\n\n\n<p>And here\u2019s how it\u2019s done using field-level validation:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import React from \"react\";\nimport { Form, Field } from \"react-final-form\";\n\nconst onSubmit = (values) =&gt; {\n  console.log(\"values: \", values);\n};\n\nconst required = (value) =&gt; (value ? undefined : \"Required\");\n\nfunction FinalFormComponent() {\n  return (\n    &lt;Form\n      onSubmit={onSubmit}\n      render={({ handleSubmit, form, submitting, pristine, values }) =&gt; (\n        &lt;form onSubmit={handleSubmit}&gt;\n          &lt;div&gt;\n            &lt;Field name=\"favoriteFood\" validate={required}&gt;\n              {({ input, meta }) =&gt; (\n                &lt;div&gt;\n                  &lt;label&gt;Favorite Food&lt;\/label&gt;\n                  &lt;input {...input} type=\"text\" placeholder=\"Favorite food\" \/&gt;\n                  {meta.error &amp;&amp; meta.touched &amp;&amp; &lt;div&gt;{meta.error}&lt;\/div&gt;}\n                &lt;\/div&gt;\n              )}\n            &lt;\/Field&gt;\n          &lt;\/div&gt;\n          &lt;button type=\"submit\"&gt;submit&lt;\/button&gt;\n        &lt;\/form&gt;\n      )}\n    \/&gt;\n  );\n}\n\nexport default FinalFormComponent;<\/pre>\n\n\n\n<h3>Summary<\/h3>\n\n\n\n<ul><li>React Final Form doesn\u2019t depend on any libraries<\/li><li>It allows you to manage which form elements gets notified of form state changes. This makes it very performant<\/li><li>Supports React Hooks<\/li><li>Supports schema-based validation through the Yup library<\/li><li>Relies on custom components that act as a wrapper for HTML form elements<\/li><li>Relies on React Context API for providing form state data to each form field<\/li><li>Final Form weighs&nbsp;<a href=\"https:\/\/bundlephobia.com\/result?p=final-form@4.19.1\" target=\"_blank\" rel=\"noreferrer noopener\">5.1Kb<\/a>&nbsp;and React Final Form weighs&nbsp;<a href=\"https:\/\/bundlephobia.com\/result?p=react-final-form@6.4.0\" target=\"_blank\" rel=\"noreferrer noopener\">3.2Kb<\/a>. This makes it very lightweight<\/li><\/ul>\n\n\n\n<h2><a href=\"https:\/\/unform.dev\/\" target=\"_blank\" rel=\"noreferrer noopener\">Unform<\/a><\/h2>\n\n\n\n<p>Unform is a performance-focused form library for React. It does so by using uncontrolled form components.<\/p>\n\n\n\n<h3>Installation<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">yarn add @unform\/core @unform\/web yup<\/pre>\n\n\n\n<h3>Basic usage<\/h3>\n\n\n\n<p>Unform requires you to create your own custom component where you use the&nbsp;<code>useField<\/code>&nbsp;Hook to access the field data and methods for interacting with the field. In the code below, we\u2019re only extracting&nbsp;<code>error<\/code>&nbsp;and&nbsp;<code>clearError<\/code>&nbsp;so we can display and clear the validation error message:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import React, { useRef } from \"react\";\nimport { useField } from \"@unform\/core\";\nexport default function Input({ name, ...inputProps }) {\n  const inputRef = useRef(null);\n  const { error, clearError } = useField(name);\n\n  return (\n    &lt;&gt;\n      &lt;input ref={inputRef} onFocus={clearError} {...inputProps} \/&gt;\n      {error &amp;&amp; &lt;span&gt;{error}&lt;\/span&gt;}\n    &lt;\/&gt;\n  );\n}<\/pre>\n\n\n\n<p>Once you have a custom component, you can now include it in your form. Unform uses a&nbsp;<code>Form<\/code>&nbsp;component as a container for form fields. This is where you add the&nbsp;<code>ref<\/code>&nbsp;and&nbsp;<code>onSubmit<\/code>&nbsp;handler. In the example below, we\u2019re also using Yup for validation. Unform doesn\u2019t include it\u2019s own validation library so you can use whichever you want for validating your forms:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import React, { useRef } from \"react\";\nimport * as Yup from \"yup\";\n\nimport { Form } from \"@unform\/web\";\nimport Input from \".\/components\/Input\";\n\nfunction UnformComponent() {\n  const formRef = useRef(null);\n\n  async function handleSubmit(data) {\n    try {\n      formRef.current.setErrors({});\n      const schema = Yup.object().shape({\n        email: Yup.string().email().required()\n      });\n      await schema.validate(data, {\n        abortEarly: false,\n      });\n      console.log(data);\n\n    } catch (err) {\n      const validationErrors = {};\n      if (err instanceof Yup.ValidationError) {\n        err.inner.forEach((error) =&gt; {\n          validationErrors[error.path] = error.message;\n        });\n        formRef.current.setErrors(validationErrors);\n      }\n    }\n  }\n\n  return (\n    &lt;Form ref={formRef} onSubmit={handleSubmit}&gt;\n      &lt;Input name=\"email\" type=\"email\" \/&gt;\n      &lt;button type=\"submit\"&gt;submit&lt;\/button&gt;\n    &lt;\/Form&gt;\n  );\n}\n\nexport default UnformComponent;<\/pre>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>Note: If you\u2019re planning to explore this library further, be sure to only follow tutorials that uses version 2. Better yet, just stick to the&nbsp;<a href=\"https:\/\/unform.dev\/\" target=\"_blank\" rel=\"noreferrer noopener\">official docs<\/a>. This is because there are some tutorials that use version 1. You can quickly determine that it\u2019s using version 1 because it uses custom form components. Version 2 embraces the use of primitive HTML elements. Check out the&nbsp;<a href=\"https:\/\/unform.dev\/migration-guide\" target=\"_blank\" rel=\"noreferrer noopener\">migration guide<\/a>&nbsp;for more information.<\/p><\/blockquote>\n\n\n\n<h3>Summary<\/h3>\n\n\n\n<ul><li>Supports React Hooks \u2014 this makes the code easier to read and maintain<\/li><li><a href=\"https:\/\/unform.dev\/guides\/react-native\/\" target=\"_blank\" rel=\"noreferrer noopener\">Supports React Native<\/a>&nbsp;by using the&nbsp;<code>@unform\/mobile<\/code>&nbsp;package<\/li><li>Uses HTML elements instead of custom components. Integration is through the use of the&nbsp;<code>useField<\/code>&nbsp;API<\/li><li>Provides easy access to form data, errors, and methods via a form ref<\/li><li>Supports complex form structures through the use of dot notation for the input name<\/li><li>Requires creation of custom form input components before it can be used<\/li><li>Unform core weighs&nbsp;<a href=\"https:\/\/bundlephobia.com\/result?p=@unform\/core@2.1.0\" target=\"_blank\" rel=\"noreferrer noopener\">3.7Kb<\/a>&nbsp;and Unform web weighs&nbsp;<a href=\"https:\/\/bundlephobia.com\/result?p=@unform\/web@2.1.0\" target=\"_blank\" rel=\"noreferrer noopener\">606 bytes<\/a><\/li><\/ul>\n\n\n\n<h2><a href=\"https:\/\/github.com\/tannerlinsley\/react-form\" target=\"_blank\" rel=\"noreferrer noopener\">React Form<\/a><\/h2>\n\n\n\n<p>React Form provides Hooks for managing form state and validating forms in React.<\/p>\n\n\n\n<h3>Installation<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">yarn add react-form<\/pre>\n\n\n\n<h3>Basic usage<\/h3>\n\n\n\n<p>The way you use React Form is similar to how you use Unform so you first have to create a custom field component that uses the&nbsp;<code>useField<\/code>&nbsp;Hook. This provides you with properties that store the field errors. Oftentimes, you\u2019ll only want to display errors once the user has already \u201ctouched\u201d the specific field. This is what the&nbsp;<code>isTouched<\/code>&nbsp;property allows you to check.<\/p>\n\n\n\n<p>To validate the field, you pass an object containing the validation function:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import React from \"react\";\nimport { useField } from \"react-form\";\n\nfunction Field({ name }) {\n  const {\n    value = \"\",\n    meta: { error, isTouched },\n    getInputProps,\n  } = useField(name, {\n    validate: (value) =&gt; {\n      if (!value) {\n        return `${name} is required.`;\n      }\n      return false;\n    },\n  });\n\n  return (\n    &lt;&gt;\n      &lt;input type=\"text\" {...getInputProps()} value={value} \/&gt;\n      {isTouched &amp;&amp; error ? &lt;span&gt;{error}&lt;\/span&gt; : null}\n    &lt;\/&gt;\n  );\n}\n\nexport default Field;<\/pre>\n\n\n\n<p>Once you have a custom field component, you can now use the&nbsp;<code>useForm<\/code>&nbsp;Hook to validate your form. Note the&nbsp;<code>Form<\/code>&nbsp;component is extracted from&nbsp;<code>useForm<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import React from \"react\";\nimport { useForm } from \"react-form\";\nimport Field from \".\/components\/Field\";\n\nfunction ReactFormComponent() {\n  const {\n    Form,\n    meta: { isSubmitting },\n  } = useForm({\n    onSubmit: async (values, instance) =&gt; {\n      console.log(\"submit: \", values);\n    },\n  });\n\n  return (\n    &lt;Form&gt;\n      &lt;label&gt;\n        Favorite Food: &lt;Field name={\"favoriteFood\"} \/&gt;\n      &lt;\/label&gt;\n\n      &lt;div&gt;\n        &lt;button type=\"submit\"&gt;Submit&lt;\/button&gt;\n      &lt;\/div&gt;\n    &lt;\/Form&gt;\n  );\n}\n\nexport default ReactFormComponent;<\/pre>\n\n\n\n<h3>Summary<\/h3>\n\n\n\n<ul><li>Supports React Hooks through the use of&nbsp;<code>useForm<\/code><\/li><li>Uses memoization for fast re-renders<\/li><li>React Form weighs&nbsp;<a href=\"https:\/\/bundlephobia.com\/result?p=react-form@4.0.1\" target=\"_blank\" rel=\"noreferrer noopener\">4.5Kb<\/a>&nbsp;when minified and gzipped<\/li><\/ul>\n\n\n\n<h2><a href=\"https:\/\/github.com\/rjsf-team\/react-jsonschema-form\" target=\"_blank\" rel=\"noreferrer noopener\">react-json-schema-form<\/a><\/h2>\n\n\n\n<p>A simple React component that allows you to build and validate HTML forms using JSON schema. It ships with simple form validation by default. Validation rules such as&nbsp;<code>required<\/code>&nbsp;and&nbsp;<code>minLength<\/code>&nbsp;are built into it. If you want to use more advanced validation rules, you\u2019ll have to write them on your own.<\/p>\n\n\n\n<p>It currently supports Bootstrap and Material UI for HTML form semantics. But you can use&nbsp;<a href=\"https:\/\/react-jsonschema-form.readthedocs.io\/en\/latest\/theme-customization\/#withtheme-higher-order-component\" target=\"_blank\" rel=\"noreferrer noopener\">your own HTML form template as well<\/a>.<\/p>\n\n\n\n<p>This library is very flexible when it comes to building forms. The only disadvantage is that there\u2019s a bit of a learning curve needed to fully use it because you\u2019re essentially using an API to build forms.<\/p>\n\n\n\n<h3>Installation<\/h3>\n\n\n\n<p>There are two built-in themes that you can use with this library. By default, there\u2019s Bootstrap:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">yarn add @rjsf\/core<\/pre>\n\n\n\n<p>But if you want to use Material UI, install the following instead:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">yarn add @rjsf\/material-ui<\/pre>\n\n\n\n<h3>Basic usage<\/h3>\n\n\n\n<p>Using the library is a three-step process:<\/p>\n\n\n\n<ol><li>Specify your schema<\/li><li>Add your custom formats and validation rules<\/li><li>Use the component<\/li><\/ol>\n\n\n\n<p>When you specify your schema, you can add the data type, label, and optionally a custom format that the user input needs to follow. If any of your fields have a custom format, you also need to supply the&nbsp;<code>customFormats<\/code>&nbsp;prop to the&nbsp;<code>Form<\/code>&nbsp;component. By default, the form will only be validated when the user submits. But you can also set the&nbsp;<code>liveValidate<\/code>&nbsp;prop to&nbsp;<code>true<\/code>&nbsp;so that it will validate the fields as the user inputs data. For custom validation, you can supply the&nbsp;<code>validate<\/code>&nbsp;prop. This is the validation function to be used for validating specific fields in your form. Lastly, the&nbsp;<code>onSubmit<\/code>&nbsp;function will only get executed once all the fields have passed validation:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import React, { Component } from \"react\";\nimport { render } from \"react-dom\";\nimport Form from \"@rjsf\/core\";\n\nconst schema = {\n  type: \"object\",\n  required: [\"email\", \"age\"],\n  properties: {\n    email: { type: \"string\", email: \"Email Address\", format: \"email_address\" },\n    age: { type: \"number\" },\n    done: { type: \"boolean\", title: \"Done?\", default: false },\n  },\n};\n\nconst customFormats = {\n  email_address: \/\\S+@\\S+\\.\\S+\/,\n};\n\nfunction validate(formData, errors) {\n  if (formData.age &lt; 18) {\n    errors.age.addError(\"You should be 18 years old or older.\");\n  }\n  return errors;\n}\n\nconst onSubmit = ({ formData }, e) =&gt; console.log(\"submit: \", formData);\n\nfunction ReactJsonSchemaComponent() {\n  return (\n    &lt;Form\n      schema={schema}\n      onSubmit={onSubmit}\n      liveValidate={true}\n      noHtml5Validate={true}\n      showErrorList={false}\n      customFormats={customFormats}\n      validate={validate}\n    \/&gt;\n  );\n}\n\nexport default ReactJsonSchemaComponent;<\/pre>\n\n\n\n<h3>Summary<\/h3>\n\n\n\n<ul><li>Automatically generate forms and apply validation rules based on JSON schema<\/li><li>Supports Bootstrap and Material UI HTML semantics<\/li><li>Requires a bit of a learning curve due to its extensive API<\/li><li>React-json-schema-form weighs&nbsp;<a href=\"https:\/\/bundlephobia.com\/result?p=react-json-schema-form@1.1.2\" target=\"_blank\" rel=\"noreferrer noopener\">1.3Kb<\/a>&nbsp;when minified and gzipped<\/li><\/ul>\n\n\n\n<h2><a href=\"https:\/\/react-hook-form.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">React Hook Form<\/a><\/h2>\n\n\n\n<p>React Hook Form is a lightweight React form validation library that mainly uses Hooks to add form validation to HTML input elements. Choose this library if you\u2019re looking for a modern form validation library that\u2019s very performant and easy to use.<\/p>\n\n\n\n<p>Out of all the libraries mentioned in this post. React Hook Form has the least amount of code you have to write in order to use it. It\u2019s only a two-step process \u2014 use the Hook then add a ref to your fields.<\/p>\n\n\n\n<p>Another great thing about this library is that it has&nbsp;<a href=\"https:\/\/react-hook-form.com\/get-started\" target=\"_blank\" rel=\"noreferrer noopener\">very good documentation<\/a>&nbsp;with&nbsp;<a href=\"https:\/\/github.com\/react-hook-form\/react-hook-form\/tree\/master\/examples\" target=\"_blank\" rel=\"noreferrer noopener\">lots of examples<\/a>. You can find guides on almost any use case you can think of such as integrating with an existing form, or how to use it with UI libraries like Material UI.<\/p>\n\n\n\n<h3>Installation<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">yarn add react-hook-form<\/pre>\n\n\n\n<h3>Basic usage<\/h3>\n\n\n\n<p>The&nbsp;<code>useForm<\/code>&nbsp;Hook provides all the data and methods required to implement form validation. First, you need to pass the&nbsp;<code>name<\/code>&nbsp;attribute which serves as the key to uniquely identify your input. Then pass a&nbsp;<code>ref<\/code>&nbsp;that uses the&nbsp;<code>register<\/code>&nbsp;function. This is what registers the uncontrolled component into the Hook. It requires you to pass the validation rules you need. Optionally, you can also pass the error message you want to show via the&nbsp;<code>message<\/code>&nbsp;property. In the example below, we used the&nbsp;<code>required<\/code>&nbsp;and&nbsp;<code>pattern<\/code>&nbsp;rule to validate an email field:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import React from 'react';\nimport { useForm } from \"react-hook-form\";\n\nfunction ReactHookFormComponent() {\n  const { register, handleSubmit, errors } = useForm();\n  const onSubmit = data =&gt; console.log(data);\n  \/\/ {\"email\":\"abc@gmail.com\"}\n\n  return (\n    &lt;form onSubmit={handleSubmit(onSubmit)}&gt;\n      &lt;input name=\"email\" ref={register({ required: true, pattern: \/\\S+@\\S+\\.\\S+\/ })} \/&gt;\n      {errors.email?.type === 'required' &amp;&amp; &lt;span&gt; This field is required&lt;\/span&gt;}\n      {errors.email?.type === 'pattern' &amp;&amp; &lt;span&gt; Invalid email&lt;\/span&gt;}\n\n      &lt;button type=\"submit\"&gt;submit&lt;\/button&gt;\n    &lt;\/form&gt;\n  );\n}\n\nexport default ReactHookFormComponent;<\/pre>\n\n\n\n<h3>Summary<\/h3>\n\n\n\n<ul><li>Uses uncontrolled form validation for optimal performance<\/li><li>Aligns with the existing HTML standard for form validation through the use of validation rules such as&nbsp;<code>required<\/code>,&nbsp;<code>min<\/code>,&nbsp;<code>max<\/code>,&nbsp;<code>pattern<\/code>, and&nbsp;<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Learn\/Forms\/Form_validation\" target=\"_blank\" rel=\"noreferrer noopener\">others<\/a><\/li><li>Supports React Native. Simply substitute HTML form elements with the React Native equivalent (eg.&nbsp;<code>TextInput<\/code>)<\/li><li>React Hook Form doesn\u2019t depend on any libraries<\/li><li>Provides you with the ability to isolate components re-render for improved performance<\/li><li>Has a&nbsp;<a href=\"https:\/\/react-hook-form.com\/form-builder\" target=\"_blank\" rel=\"noreferrer noopener\">form builder utility<\/a>&nbsp;if you want to quickly create trivial forms<\/li><li>Supports schema-based validation through the Yup library<\/li><li>Has great documentation and example usage<\/li><li>React Hook Form weighs&nbsp;<a href=\"https:\/\/bundlephobia.com\/result?p=react-hook-form@5.6.3\" target=\"_blank\" rel=\"noreferrer noopener\">9Kb<\/a>&nbsp;when minified and gzipped<\/li><\/ul>\n\n\n\n<h2><a href=\"https:\/\/redux-form.com\/8.3.0\/\" target=\"_blank\" rel=\"noreferrer noopener\">Redux Form<\/a><\/h2>\n\n\n\n<p>Redux Form allows you to manage your form state (form input values, form errors, etc.) by means of Redux. Redux Form uses the store for keeping track of form state, thus the main disadvantage of this library is its performance. Even if you\u2019re already using Redux in your application, only use it if you need tight coupling between your existing Redux state and your form data.<\/p>\n\n\n\n<h3>Installation<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">yarn add redux-form redux react-redux<\/pre>\n\n\n\n<h3>Basic usage<\/h3>\n\n\n\n<p>To use Redux Form, you need to extract the&nbsp;<code>Field<\/code>&nbsp;component and the&nbsp;<code>reduxForm<\/code>&nbsp;higher-order component from&nbsp;<code>redux-form<\/code>. At a minimum configuration, all you need is to pass a unique name for the form (in this case it\u2019s&nbsp;<code>bio<\/code>). But here, we\u2019re also passing in a validation function. This gets executed when the user submits the form.<\/p>\n\n\n\n<p>To create an input field, you use the&nbsp;<code>Field<\/code>&nbsp;component. Here, we pass in the&nbsp;<code>type<\/code>,&nbsp;<code>name<\/code>,&nbsp;<code>component<\/code>&nbsp;to be used for rendering, and the&nbsp;<code>label<\/code>. The&nbsp;<code>renderField()<\/code>&nbsp;function is responsible for returning the input component. Aside from rendering the label and input, it also renders the error messages. This is made possible by Redux Form\u2019s&nbsp;<code>Field<\/code>&nbsp;component:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import React from 'react';\nimport { Field, reduxForm } from 'redux-form';\n\nconst validate = values =&gt; {\n  const errors = {}\n  if (!values.name) {\n    errors.name = 'Required';\n  }\n\n  if (!values.email) {\n    errors.email = 'Required';\n  } else if (!\/\\S+@\\S+\\.\\S+\/i.test(values.email)) {\n    errors.email = 'Invalid email address'\n  }\n  return errors;\n}\n\nconst renderField = ({\n  input,\n  label,\n  type,\n  meta: { touched, error }\n}) =&gt; (\n  &lt;div&gt;\n    &lt;label&gt;{label}&lt;\/label&gt;\n    &lt;div&gt;\n      &lt;input {...input} placeholder={label} type={type} \/&gt;\n      {touched &amp;&amp; (error &amp;&amp; &lt;span&gt;{error}&lt;\/span&gt;)}\n    &lt;\/div&gt;\n  &lt;\/div&gt;\n);\n\nlet BioForm = props =&gt; {\n  const { handleSubmit } = props;\n  return (\n    &lt;form onSubmit={handleSubmit}&gt;\n      &lt;div&gt;\n        &lt;Field type=\"text\" name=\"name\" component={renderField} label=\"Name\" \/&gt;\n      &lt;\/div&gt;\n      &lt;div&gt;\n        &lt;Field type=\"email\" name=\"email\" component={renderField} label=\"Email\" \/&gt;\n      &lt;\/div&gt;\n      &lt;button type=\"submit\"&gt;Submit&lt;\/button&gt;\n    &lt;\/form&gt;\n  );\n}\n\nBioForm = reduxForm({\n  form: 'bio',\n  validate\n})(BioForm);\n\nexport default BioForm;<\/pre>\n\n\n\n<p>To bring it all together, include the&nbsp;<code>formReducer<\/code>&nbsp;to your existing reducers then pass an&nbsp;<code>onSubmit<\/code>&nbsp;handler to your form component:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import React, { Component } from 'react';\nimport { createStore, combineReducers } from 'redux';\nimport { reducer as formReducer } from 'redux-form';\nimport { Provider } from 'react-redux';\nimport BioForm from '.\/components\/BioForm';\n\nconst rootReducer = combineReducers({\n  \/\/ your existing reducers..\n  form: formReducer\n});\n\nconst store = createStore(rootReducer);\n\nclass ReduxFormComponent extends Component {\n  submit = values =&gt; {\n    console.log('submit: ', values);\n  }\n\n  render() {\n    return (\n      &lt;Provider store={store}&gt;\n        &lt;BioForm onSubmit={this.submit} \/&gt;\n      &lt;\/Provider&gt;\n    );\n  }\n}\n\nexport default ReduxFormComponent;<\/pre>\n\n\n\n<h3>Summary<\/h3>\n\n\n\n<ul><li>Redux Form manages the form state through the Redux library<\/li><li>Heavier than most libraries mentioned here. It weighs&nbsp;<a href=\"https:\/\/bundlephobia.com\/result?p=redux-form@7.1.2\" target=\"_blank\" rel=\"noreferrer noopener\">24.4Kb<\/a>&nbsp;(minified + gzipped)<\/li><li>Redux Form can only be used with React and Redux<\/li><li>Redux Form is only useful if there\u2019s a need for tight coupling between existing Redux state and form data<\/li><\/ul>\n\n\n\n<h2><a href=\"https:\/\/github.com\/formsy\/formsy-react\" target=\"_blank\" rel=\"noreferrer noopener\">Formsy<\/a><\/h2>\n\n\n\n<p>Formsy is a form input builder and validator for React. It uses simple syntax for form validation rules. It also includes handlers for different form states such as&nbsp;<code>onSubmit<\/code>&nbsp;and&nbsp;<code>isValid<\/code>. Formsy is a good choice if you\u2019re looking for an all in one solution for building and managing forms. Though the biggest downside with this library is that it doesn\u2019t support React Hooks.<\/p>\n\n\n\n<h3>Installation<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">yarn add formsy-react<\/pre>\n\n\n\n<h3>Basic usage<\/h3>\n\n\n\n<p>Formsy has a similarity with Unform as it requires you to create your own custom component that\u2019s wrapped with the&nbsp;<code>withFormsy<\/code>&nbsp;higher-order component. This provides all the properties and methods required to manipulate the input component and conditionally display error messages:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import React, { Component } from 'react';\nimport { withFormsy } from 'formsy-react';\n\nclass FormsyInput extends Component {\n  constructor(props) {\n    super(props);\n    this.changeValue = this.changeValue.bind(this);\n  }\n\n  changeValue(event) {\n    this.props.setValue(event.currentTarget.value);\n  }\n\n  render() {\n    const errorMessage = this.props.errorMessage;\n\n    return (\n      &lt;div&gt;\n        &lt;input onChange={this.changeValue} type=\"text\" value={this.props.value || ''} \/&gt;\n        &lt;span&gt;{!this.props.isPristine ? errorMessage : ''}&lt;\/span&gt;\n      &lt;\/div&gt;\n    );\n  }\n}\n\nexport default withFormsy(FormsyInput);<\/pre>\n\n\n\n<p>Once you\u2019ve created a custom component, you can now use it in your forms. To create a form, you should use the&nbsp;<code>Formsy<\/code>&nbsp;component. This requires the&nbsp;<code>onValidSubmit<\/code>&nbsp;prop. This only gets executed if all the form fields has a valid input. In the example below, we used the&nbsp;<code>isEmail<\/code>&nbsp;validator, but there are&nbsp;<a href=\"https:\/\/github.com\/formsy\/formsy-react\/blob\/master\/API.md#validators\" target=\"_blank\" rel=\"noreferrer noopener\">many others<\/a>&nbsp;you can use:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import React, { Component } from 'react';\nimport Formsy from 'formsy-react';\nimport FormsyInput from '.\/components\/FormsyInput';\n\nexport default class App extends Component {\n\n  submit(model) {\n    console.log('valid form: ', model);\n    \/\/ {email: \"abc@gmail.com\"}\n  }\n\n  render() {\n    return (\n      &lt;Formsy onValidSubmit={this.submit}&gt;\n        &lt;FormsyInput name=\"email\" validations=\"isEmail\" validationError=\"This is not a valid email\" required \/&gt;\n        &lt;button type=\"submit\"&gt;\n          Submit\n        &lt;\/button&gt;\n      &lt;\/Formsy&gt;\n    );\n  }\n}<\/pre>\n\n\n\n<h3>Summary<\/h3>\n\n\n\n<ul><li>Formsy is one of the older React form validation libraries out there<\/li><li>Includes its own validation rules like&nbsp;<code>isEmail<\/code>&nbsp;and<code>isUrl<\/code><\/li><li>Requires creation of custom form input component before it can be used<\/li><li>Has no official support for React Hooks which makes the code look more complex<\/li><li>Formsy weighs&nbsp;<a href=\"https:\/\/bundlephobia.com\/result?p=formsy-react@2.0.3\" target=\"_blank\" rel=\"noreferrer noopener\">9.9Kb<\/a>&nbsp;when minified and gzipped<\/li><\/ul>\n\n\n\n<h2><a href=\"https:\/\/github.com\/dockwa\/simple-react-validator\" target=\"_blank\" rel=\"noreferrer noopener\">Simple React Validator<\/a><\/h2>\n\n\n\n<p>Simple React Validator is a&nbsp;<a href=\"https:\/\/laravel.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">Laravel-inspired<\/a>&nbsp;React form validation library. Out of all the libraries we\u2019ve gone through in this article, this one has the biggest collection of&nbsp;<a href=\"https:\/\/github.com\/dockwa\/simple-react-validator#rules\" target=\"_blank\" rel=\"noreferrer noopener\">built-in validation rules<\/a>.<\/p>\n\n\n\n<h3>Installation<\/h3>\n\n\n\n<pre class=\"wp-block-preformatted\">yarn add simple-react-validator<\/pre>\n\n\n\n<h3>Basic usage<\/h3>\n\n\n\n<p>The example in the GitHub repo doesn\u2019t really use Hooks so you have to dig a bit deeper to find out how to use it with Hooks. In the code below, you can see that it mainly uses controlled components so you have to manage the form state independently. Another downside of this library is that you have to use&nbsp;<code>forceUpdate<\/code>&nbsp;every time you need to show the error messages:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import React, { useState, useRef } from \"react\";\nimport SimpleReactValidator from \"simple-react-validator\";\n\nfunction SimpleReactValidatorComponent() {\n  const [email, setEmail] = useState(\"\");\n  const simpleValidator = useRef(new SimpleReactValidator());\n  const [, forceUpdate] = useState();\n\n  const form = React.createRef();\n\n  const submitForm = () =&gt; {\n    const formValid = simpleValidator.current.allValid();\n    if (!formValid) {\n      simpleValidator.current.showMessages(true);\n      forceUpdate(1)\n    } else {\n      console.log('submit form.');\n    }\n  };\n\n  return (\n    &lt;form ref={form}&gt;\n      &lt;label&gt;Email&lt;\/label&gt;\n      &lt;input\n        name=\"email\"\n        type=\"text\"\n        value={email}\n        onChange={(e) =&gt; setEmail(e.target.value)}\n        onBlur={() =&gt; {\n          simpleValidator.current.showMessageFor(\"email\")\n          forceUpdate(1);\n        }}\n      \/&gt;\n\n      {simpleValidator.current.message(\"email\", email, \"required|email\")}\n      &lt;button type=\"button\" onClick={submitForm}&gt;submit&lt;\/button&gt;\n    &lt;\/form&gt;\n  );\n}\n\nexport default SimpleReactValidatorComponent;<\/pre>\n\n\n\n<h3>Summary<\/h3>\n\n\n\n<ul><li>Lots of built-in validation rules that are based from Laravel<\/li><li>Uses the state for form state management<\/li><li>Has localization support for error messages<\/li><li>Has no official React Hooks support<\/li><li>Simple React Validator weighs&nbsp;<a href=\"https:\/\/bundlephobia.com\/result?p=simple-react-validator@1.4.6\" target=\"_blank\" rel=\"noreferrer noopener\">4Kb<\/a>&nbsp;when minified and gzipped<\/li><\/ul>\n\n\n\n<h2>Form validation libraries to avoid<\/h2>\n\n\n\n<p>If you\u2019re starting a new project or is simply looking for a modern and actively maintained library, it\u2019s best to avoid the following libraries. These libraries are either no longer being actively maintained or use an outdated React API:<\/p>\n\n\n\n<ul><li><a href=\"https:\/\/github.com\/jquense\/react-formal\" target=\"_blank\" rel=\"noreferrer noopener\">React-Formal<\/a><\/li><li><a href=\"https:\/\/github.com\/prometheusresearch-archive\/react-forms\" target=\"_blank\" rel=\"noreferrer noopener\">React-forms<\/a><\/li><li><a href=\"https:\/\/github.com\/VoliJS\/NestedLink\" target=\"_blank\" rel=\"noreferrer noopener\">Value Link<\/a><\/li><li><a href=\"https:\/\/github.com\/insin\/newforms\" target=\"_blank\" rel=\"noreferrer noopener\">newforms<\/a><\/li><li><a href=\"https:\/\/github.com\/zackify\/formjs\" target=\"_blank\" rel=\"noreferrer noopener\">formjs<\/a><\/li><li><a href=\"https:\/\/github.com\/gcanti\/tcomb-form\" target=\"_blank\" rel=\"noreferrer noopener\">tcomb-form<\/a><\/li><\/ul>\n\n\n\n<h2>Other form libraries<\/h2>\n\n\n\n<p>Here\u2019s a list of other form libraries to explore. These are mostly doing the same thing as the libraries we\u2019ve gone through so I\u2019ll just leave you to explore them for yourself:<\/p>\n\n\n\n<ul><li><a href=\"https:\/\/github.com\/redux-autoform\/redux-autoform\" target=\"_blank\" rel=\"noreferrer noopener\">Redux Autoform<\/a><\/li><li><a href=\"https:\/\/github.com\/vazco\/uniforms\" target=\"_blank\" rel=\"noreferrer noopener\">uniforms<\/a><\/li><li><a href=\"https:\/\/github.com\/bietkul\/react-reactive-form\" target=\"_blank\" rel=\"noreferrer noopener\">React Reactive Forms<\/a><\/li><li><a href=\"https:\/\/github.com\/ismaelga\/react-json-editor\" target=\"_blank\" rel=\"noreferrer noopener\">react-json-editor<\/a><\/li><\/ul>\n\n\n\n<h2>Conclusion<\/h2>\n\n\n\n<p>In this article, we\u2019ve taken a look at some of the most popular and interesting React form validation libraries out there. As you have seen, most of them have a similar intuitive API for managing forms and validation errors. Each one has its own pros and cons based on your needs. But for most cases, you won\u2019t go wrong with either Formik, React Final Form, or React Hook Form.<\/p>\n\n\n\n<p>This article was simply a roundup of form solutions available for React. If you need a more technical comparison, be sure to read the following \u2014&nbsp;<a href=\"https:\/\/blog.logrocket.com\/react-hook-form-vs-formik-a-technical-and-performance-comparison\/\" target=\"_blank\" rel=\"noreferrer noopener\">React Hook Form vs. Formik: A technical and performance comparison<\/a>.<\/p>\n\n\n\n<h2>Full visibility into production React apps<\/h2>\n\n\n\n<p>Debugging React applications can be difficult, especially when users experience issues that are difficult to reproduce. If you\u2019re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time,&nbsp;<a href=\"https:\/\/www2.logrocket.com\/react-performance-monitoring\">try LogRocket<\/a>.&nbsp;<a href=\"https:\/\/www2.logrocket.com\/react-performance-monitoring\" target=\"_blank\" rel=\"noreferrer noopener\"><\/a><a href=\"https:\/\/www2.logrocket.com\/react-performance-monitoring\" target=\"_blank\" rel=\"noreferrer noopener\"><\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/www2.logrocket.com\/react-performance-monitoring\" target=\"_blank\" rel=\"noreferrer noopener\">LogRocket<\/a>&nbsp;is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app&#8217;s performance, reporting with metrics like client CPU load, client memory usage, and more.<\/p>\n\n\n\n<p>The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.<\/p>\n\n\n\n<p>Modernize how you debug your React apps \u2014&nbsp;<a href=\"https:\/\/www2.logrocket.com\/react-performance-monitoring\" target=\"_blank\" rel=\"noreferrer noopener\">start monitoring for free<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As a developer, it\u2019s usually best to not reinvent the wheel. That\u2019s why the first step for implementing a solution is to look for existing solutions. And it\u2019s what React is all about \u2014 creating reusable components so we don\u2019t end up repeating ourselves.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/posts\/1405"}],"collection":[{"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1405"}],"version-history":[{"count":1,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/posts\/1405\/revisions"}],"predecessor-version":[{"id":1406,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=\/wp\/v2\/posts\/1405\/revisions\/1406"}],"wp:attachment":[{"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1405"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1405"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lvboard.infostore.in.ua\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1405"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}