{"data":{"allMarkdownRemark":{"edges":[{"node":{"id":"800a446b-0861-54ed-a2e3-a36e545abef1","frontmatter":{"category":"Coding","title":"The concept of SubForms - with React and Formik","date":"2019-07-02","summary":"Create forms at scale with Formik and Yup","thumbnail":{"relativePath":"pages/the-concept-of-subforms-with-formik/thumbnail.png","childImageSharp":{"resolutions":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAAsSAAALEgHS3X78AAABcklEQVQ4y51UzcqCQBSdN+st3AluXOTel6htL2FBuDDaBFGRZGSEuOiHoKI2RbXsR/N83AFjkMbsuzCMjHfOnHvOnWHIRJIk71k2xLxssE+LsmSK1+uVC8pkYLTxdrvh8XjwOf3+dqgU8H6/o9PpYDAYwPd9TCYTuK6L6XSaCyoFfD6fsCwL3W4Xi8UC8/kc2+2Wg8dx/DsgMWw0GqjX6+j3+2i1WhiPx/8vmRjato3hcIjdbof9fs+Zinm5DLPOkQnNZpOzdBwHYRi+zcpzmmXZiQnX6xXL5RKbzYbrl2qXzRX3sE+aHA4HXC6XjxpFUYTj8SjVkokNS3E6naCqKi8zCAKsViveKqTlaDTi7VOpVNBut7nOUoYp4Hq9hmEYqNVqKJfLUBQF1WqVH6LrOkzThKZpKJVKOJ/P30umUkk3SiZDqFVIgtlsxtc9z0Ov1+P9mZYu6smK3mFZSDUUHUvbglxN2yQ76F8hl/OerSJP2R9ITMR6qwehxQAAAABJRU5ErkJggg==","width":395,"height":325,"src":"/static/631a33919834353b3dda8e8578592a5b/b3029/thumbnail.png","srcSet":"/static/631a33919834353b3dda8e8578592a5b/b3029/thumbnail.png 1x,\n/static/631a33919834353b3dda8e8578592a5b/8d141/thumbnail.png 1.5x,\n/static/631a33919834353b3dda8e8578592a5b/ee72c/thumbnail.png 2x"}}},"authorName":"Nicholas Peretti","authorDescription":"Software Engineer","authorAvatar":{"relativePath":"pages/the-concept-of-subforms-with-formik/avatar.jpg","childImageSharp":{"resolutions":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAMFBP/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAcKk+4zgAAf/xAAZEAEAAgMAAAAAAAAAAAAAAAACAQMQEiD/2gAIAQEAAQUCJlJVI4M6oXGs8f/EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQMBAT8BH//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQIBAT8BH//EABsQAQACAgMAAAAAAAAAAAAAAAEAAhAgITFC/9oACAEBAAY/AgO2cmBlvTbX/8QAGxABAQACAwEAAAAAAAAAAAAAAREAIRAgQVH/2gAIAQEAAT8hBOpDNUohZx7hMll+40df/9oADAMBAAIAAwAAABBDwAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/EB//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/EB//xAAcEAEBAAICAwAAAAAAAAAAAAABESFBADEQIFH/2gAIAQEAAT8QxBALK8VVkQLA7X54WBCyOzfKvBj0MduVz6//2Q==","width":50,"height":50,"src":"/static/9347eae31d09e05f032d02892f955d38/d2d31/avatar.jpg","srcSet":"/static/9347eae31d09e05f032d02892f955d38/d2d31/avatar.jpg 1x,\n/static/9347eae31d09e05f032d02892f955d38/0b804/avatar.jpg 1.5x,\n/static/9347eae31d09e05f032d02892f955d38/753c3/avatar.jpg 2x,\n/static/9347eae31d09e05f032d02892f955d38/31ca8/avatar.jpg 3x"}}},"headerImage":{"relativePath":"pages/the-concept-of-subforms-with-formik/headerImage.png","childImageSharp":{"resolutions":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAAsSAAALEgHS3X78AAAAUUlEQVQY06WOIQ4AMQgE+/8nYSoQaExFRQmSH4AovX7gkiM3djOZbecH7W2IiDGGqu69y7K7997NrFzOzLXWnFNEbrwm36vMjIgAQETl2194AJcvYFpZxM6mAAAAAElFTkSuQmCC","width":1280,"height":384,"src":"/static/8ce613d93c9ee2f1e3b248f2aabe8efc/26421/headerImage.png","srcSet":"/static/8ce613d93c9ee2f1e3b248f2aabe8efc/26421/headerImage.png 1x,\n/static/8ce613d93c9ee2f1e3b248f2aabe8efc/34a7a/headerImage.png 1.5x"}}}},"html":"<p>In the last few months I’ve been working a lot with forms. I had to do a large refactoring in one of AUTO1’s applications, and through all the research, I also encountered the term <strong>subform</strong>. The concept was troublesome not only for me.\nI found more than one issue on the Formik repository about developers asking for help.\nIn this article I'll try to clarify this concept and show you how to use it properly.</p>\n<h2>What the heck is a subform anyway?</h2>\n<p>If you’ve ever worked on a medium-large project with a reasonable amount of forms, you might have probably noticed that you could potentially reuse a lot of fields, sometimes even entire forms!\nThat’s the core of the subform concept: reusable components (fields or group of fields) that can be composed together to create bigger forms.</p>\n<p>At the beginning I had a lot of questions in my mind like:</p>\n<ul>\n<li>How can I handle validation?</li>\n<li>How can I handle form state?</li>\n<li>How can I stay flexible?</li>\n</ul>\n<p>These questions and many others appeared while I was refactoring existing codebase. Many similar questions created by other developers appeared in the Formik repository as issues.</p>\n<p>Don’t get me wrong: implementing scalable validation for a single form is not that hard. The complicated thing is to keep validation and state flexible while you write your subforms. What does it mean? We’ll see that in a moment.</p>\n<h2>How Formik can help</h2>\n<p>Formik is an amazing library, one of the bests for this job, and here’s what it brings to the table:</p>\n<h3>Auto-connected Field component</h3>\n<p>Formik provides a Field component that, thanks to the React Context API, will be automatically connected to the Form component that wraps our Field, regardless of how deep our Field is in the tree.</p>\n<h3>Yup validation schema</h3>\n<p>Yup is a library to create validation schemas. This library is very similar to the prop-types of React, so it is very simple to start using it.\nFormik supports Yup natively, so you just need to define the schema and pass it to Formik, it will take care of the rest.</p>\n<p>So this is how Formik will make our life easier not only while creating subforms but also when we’ll need to maintain them!</p>\n<h2>Enough talking, show me the code</h2>\n<p>Let’s create our first subform! Before we start, we need to clarify what <strong>our subform will be responsible</strong> for:</p>\n<ul>\n<li>Provide a basic validation schema</li>\n<li>Provide some default values (required by Formik)</li>\n<li>Provide the list of its fields (in case we need to access the data from outside, as we’ll see later)</li>\n<li>Provide a React component that will render the subform to the user and its fields’ errors</li>\n</ul>\n<p>In our case, we're going to create a form that allows to create a new user.\nWe'll need to display the following fields:</p>\n<ul>\n<li>First name</li>\n<li>Last name</li>\n<li>Email</li>\n<li>Password</li>\n</ul>\n<p>Just keep it simple. So, let’s create our <code class=\"language-text\">NewUserSubForm</code> directory and our <code class=\"language-text\">fieldsNames</code> file. It’s just a file that exports constants, don’t worry. It will look like this:</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token comment\">//  UserSubform/fieldsNames.js</span>\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token constant\">FIRST_NAME</span> <span class=\"token operator\">=</span> <span class=\"token string\">'firstName'</span>\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token constant\">LAST_NAME</span> <span class=\"token operator\">=</span> <span class=\"token string\">'lastName'</span>\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token constant\">EMAIL</span> <span class=\"token operator\">=</span> <span class=\"token string\">'email'</span>\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token constant\">PASSWORD</span> <span class=\"token operator\">=</span> <span class=\"token string\">'password'</span></code></pre></div>\n<h3>Defining the validation schema</h3>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token comment\">//  UserSubform/validationSchema.js</span>\n<span class=\"token keyword\">import</span> <span class=\"token operator\">*</span> <span class=\"token keyword\">as</span> yup <span class=\"token keyword\">from</span> <span class=\"token string\">'yup'</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> <span class=\"token constant\">FIRST_NAME</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">LAST_NAME</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">EMAIL</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">PASSWORD</span> <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'./fieldsNames'</span>\n\n<span class=\"token keyword\">const</span> <span class=\"token constant\">MIN_PASSWORD_LENGTH</span> <span class=\"token operator\">=</span> <span class=\"token number\">8</span>\n\n<span class=\"token keyword\">const</span> <span class=\"token constant\">REQUIRED_MESSAGE</span> <span class=\"token operator\">=</span> <span class=\"token string\">'This field is required'</span>\n<span class=\"token keyword\">const</span> <span class=\"token constant\">INVALID_EMAIL_FORMAT</span> <span class=\"token operator\">=</span> <span class=\"token string\">'Invalid email format'</span>\n<span class=\"token keyword\">const</span> <span class=\"token constant\">PASSWORD_TOO_SHOWRT</span> <span class=\"token operator\">=</span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">The password must be at least </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token constant\">MIN_PASSWORD_LENGTH</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\"> characters long</span><span class=\"token template-punctuation string\">`</span></span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> yup<span class=\"token punctuation\">.</span><span class=\"token function\">object</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n  <span class=\"token punctuation\">[</span><span class=\"token constant\">FIRST_NAME</span><span class=\"token punctuation\">]</span><span class=\"token operator\">:</span> yup<span class=\"token punctuation\">.</span><span class=\"token function\">string</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">required</span><span class=\"token punctuation\">(</span><span class=\"token constant\">REQUIRED_MESSAGE</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">[</span><span class=\"token constant\">LAST_NAME</span><span class=\"token punctuation\">]</span><span class=\"token operator\">:</span> yup<span class=\"token punctuation\">.</span><span class=\"token function\">string</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">required</span><span class=\"token punctuation\">(</span><span class=\"token constant\">REQUIRED_MESSAGE</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">[</span><span class=\"token constant\">EMAIL</span><span class=\"token punctuation\">]</span><span class=\"token operator\">:</span> yup\n    <span class=\"token punctuation\">.</span><span class=\"token function\">string</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">required</span><span class=\"token punctuation\">(</span><span class=\"token constant\">REQUIRED_MESSAGE</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">email</span><span class=\"token punctuation\">(</span><span class=\"token constant\">INVALID_EMAIL_FORMAT</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">[</span><span class=\"token constant\">PASSWORD</span><span class=\"token punctuation\">]</span><span class=\"token operator\">:</span> yup\n    <span class=\"token punctuation\">.</span><span class=\"token function\">string</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">required</span><span class=\"token punctuation\">(</span><span class=\"token constant\">REQUIRED_MESSAGE</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">min</span><span class=\"token punctuation\">(</span><span class=\"token constant\">MIN_PASSWORD_LENGTH</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">PASSWORD_TOO_SHOWRT</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>We’ve just defined our validation schema regardless the markup of our form. This file just contains all the validation logic and has one responsibility. If in the future we’ll need to add some more validation options, we’ll just need to change it here.</p>\n<p>Now it’s time for the default values. Initial values are <strong>required</strong> from Formik because it uses controlled inputs. So, if you don’t specify those values, you’ll get and error from React as soon as you try to change the content of the input.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token comment\">//  UserSubform/defaultValues.js</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> <span class=\"token constant\">FIRST_NAME</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">LAST_NAME</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">EMAIL</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">PASSWORD</span> <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'./fieldsNames'</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token punctuation\">[</span><span class=\"token constant\">FIRST_NAME</span><span class=\"token punctuation\">]</span><span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">[</span><span class=\"token constant\">LAST_NAME</span><span class=\"token punctuation\">]</span><span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">[</span><span class=\"token constant\">EMAIL</span><span class=\"token punctuation\">]</span><span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">[</span><span class=\"token constant\">PASSWORD</span><span class=\"token punctuation\">]</span><span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h3>Rendering the subform</h3>\n<p>And now the master piece: The React component. Remember: <strong>we just need to use the Fields and not the Formik or the Form components</strong>.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token comment\">//  UserSubform/index.js</span>\n<span class=\"token keyword\">import</span> React<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> Fragment <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'react'</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> Field<span class=\"token punctuation\">,</span> ErrorMessage <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'formik'</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> <span class=\"token constant\">FIRST_NAME</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">LAST_NAME</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">EMAIL</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">PASSWORD</span> <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'./fieldsNames'</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">NewUserSubForm</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">React<span class=\"token punctuation\">.</span>Component</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n      <span class=\"token operator\">&lt;</span>Fragment<span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>Field component<span class=\"token operator\">=</span><span class=\"token string\">\"input\"</span> name<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token constant\">FIRST_NAME</span><span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>ErrorMessage name<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token constant\">FIRST_NAME</span><span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>Field component<span class=\"token operator\">=</span><span class=\"token string\">\"input\"</span> name<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token constant\">LAST_NAME</span><span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>ErrorMessage name<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token constant\">LAST_NAME</span><span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>Field component<span class=\"token operator\">=</span><span class=\"token string\">\"input\"</span> name<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token constant\">EMAIL</span><span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>ErrorMessage name<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token constant\">EMAIL</span><span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>Field component<span class=\"token operator\">=</span><span class=\"token string\">\"input\"</span> name<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token constant\">PASSWORD</span><span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>ErrorMessage name<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token constant\">PASSWORD</span><span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n      <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>Fragment<span class=\"token operator\">></span>\n    <span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>And that’s it. In this phase we can test every single part of our subform: validation, the default values schema and the React component.</p>\n<p><strong>A piece of advice</strong>: Formik sets the fields’ values in its state using the <code class=\"language-text\">name</code> property, but the cool thing is that it uses it like the Lodash <code class=\"language-text\">set</code> function. It means that we can write the name of a field like this: <code class=\"language-text\">user.firstName</code>. In this way Formik will create an object in its state called <code class=\"language-text\">user</code>, and then a property inside of <code class=\"language-text\">user</code> called <code class=\"language-text\">firstName</code> that will contain the value of our field.</p>\n<p>This mechanism gives us power to improve the flexibility of our subform. How?</p>\n<h3>Making a subform flexible</h3>\n<p>Let’s edit our component in a way that it will accept an optional property called <code class=\"language-text\">namespace</code>. If received, the component will prepend the namespace to every field name. In this way it will be easier to wrap all the subform’s values under a certain object in the main form.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token comment\">//  UserSubform/index.js</span>\n<span class=\"token keyword\">import</span> React<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> Fragment <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'react'</span>\n<span class=\"token keyword\">import</span> PropTypes <span class=\"token keyword\">from</span> <span class=\"token string\">'prop-types'</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> Field<span class=\"token punctuation\">,</span> ErrorMessage <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'formik'</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> <span class=\"token constant\">FIRST_NAME</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">LAST_NAME</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">EMAIL</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">PASSWORD</span> <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'./fieldsNames'</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">NewUserSubForm</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">React<span class=\"token punctuation\">.</span>Component</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">static</span> propTypes <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n    namespace<span class=\"token operator\">:</span> PropTypes<span class=\"token punctuation\">.</span>string<span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">withNamespace</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">fieldName</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> namespace <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props\n\n    <span class=\"token keyword\">return</span> namespace <span class=\"token operator\">?</span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>namespace<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">.</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>fieldName<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span> <span class=\"token operator\">:</span> fieldName\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> withNamespace <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span>\n\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n      <span class=\"token operator\">&lt;</span>Fragment<span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>Field component<span class=\"token operator\">=</span><span class=\"token string\">\"input\"</span> name<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token function\">withNamespace</span><span class=\"token punctuation\">(</span><span class=\"token constant\">FIRST_NAME</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>ErrorMessage name<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token function\">withNamespace</span><span class=\"token punctuation\">(</span><span class=\"token constant\">FIRST_NAME</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>Field component<span class=\"token operator\">=</span><span class=\"token string\">\"input\"</span> name<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token function\">withNamespace</span><span class=\"token punctuation\">(</span><span class=\"token constant\">LAST_NAME</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>ErrorMessage name<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token function\">withNamespace</span><span class=\"token punctuation\">(</span><span class=\"token constant\">FIRST_NAME</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>Field component<span class=\"token operator\">=</span><span class=\"token string\">\"input\"</span> name<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token function\">withNamespace</span><span class=\"token punctuation\">(</span><span class=\"token constant\">EMAIL</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>ErrorMessage name<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token function\">withNamespace</span><span class=\"token punctuation\">(</span><span class=\"token constant\">FIRST_NAME</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>Field component<span class=\"token operator\">=</span><span class=\"token string\">\"input\"</span> name<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token function\">withNamespace</span><span class=\"token punctuation\">(</span><span class=\"token constant\">PASSWORD</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&lt;</span>ErrorMessage name<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token function\">withNamespace</span><span class=\"token punctuation\">(</span><span class=\"token constant\">FIRST_NAME</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n      <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>Fragment<span class=\"token operator\">></span>\n    <span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>We don’t need to do that with the other parts of the subform, the main form will be responsible for that. And, about the main form, let’s see how to implement it!</p>\n<h2>The main form</h2>\n<p>Finally, we’re going to create our main form component. Let’s define its responsibilities just like we did with our subform. The main form will be responsible for:</p>\n<ul>\n<li>Compose the validation</li>\n<li>Compose the React components</li>\n<li>Compose and eventually overwrite the default values</li>\n<li>Orchestrate all the above elements in the right way (if we add a namespace for a subform we should put its validation schema under the same namespace)</li>\n<li>Handle the submission of the form</li>\n<li>Handle the display logic of the server-side errors (and all the form level errors)</li>\n</ul>\n<p>It's a lot of responsibilities, <em>and that’s all right</em>. The main form represents a specific point in the UI/UX where the user needs to insert some data. In our case, it could be a registration form, but it could also be a registration combined with a purchase, just like when you buy something from amazon and you agree to sign up in the process.</p>\n<p>The point is: <strong>A Form is a unique component that represent a specific use case</strong>, so it has to be designed accordingly. That’s why it makes no sense to create a “god-form” component with hundreds of props that decides which endpoint the form is going to use. It just creates useless complexity.</p>\n<p>In my opinion, the best way to organize this approach is to create a folder where you’ll store all your subforms. Every subform will be represented by its directory and it will contain all its parts: validation, values, fields and the React component.\nA main form, instead, should be created ad-hoc to fit the needs of a certain use case, for example inside a certain route.</p>\n<p>So, with that in mind, let’s proceed to the implementation. We’ll have our directory called <code class=\"language-text\">registrationForm</code> and it will have the same parts of a subform:</p>\n<p>Fields Names</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token comment\">//  CreateNewUserRoute/form/fieldsNames.js</span>\n<span class=\"token keyword\">export</span> <span class=\"token punctuation\">{</span> <span class=\"token constant\">FIRST_NAME</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">LAST_NAME</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">EMAIL</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">PASSWORD</span> <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'./subforms/NewUserSubForm/fieldsNames'</span>\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">const</span> <span class=\"token constant\">USER</span> <span class=\"token operator\">=</span> <span class=\"token string\">'user'</span></code></pre></div>\n<p>Validation</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token comment\">//  CreateNewUserRoute/form/validationSchema.js</span>\n<span class=\"token keyword\">import</span> <span class=\"token operator\">*</span> <span class=\"token keyword\">as</span> yup <span class=\"token keyword\">from</span> <span class=\"token string\">'yup'</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> <span class=\"token constant\">USER</span> <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'./fieldsNames'</span>\n<span class=\"token keyword\">import</span> userValidationSchema <span class=\"token keyword\">from</span> <span class=\"token string\">'./subforms/NewUserSubForm/validationSchema'</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> yup<span class=\"token punctuation\">.</span><span class=\"token function\">object</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n  <span class=\"token punctuation\">[</span><span class=\"token constant\">USER</span><span class=\"token punctuation\">]</span><span class=\"token operator\">:</span> userValidationSchema<span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>Default values</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token comment\">//  CreateNewUserRoute/form/defaultValues.js</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> <span class=\"token constant\">USER</span> <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'./field Names'</span>\n<span class=\"token keyword\">import</span> userDefaultValues <span class=\"token keyword\">from</span> <span class=\"token string\">'./subforms/NewUserSubForm/defaultValues'</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token punctuation\">[</span><span class=\"token constant\">USER</span><span class=\"token punctuation\">]</span><span class=\"token operator\">:</span> userDefaultValues<span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The React component</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token comment\">//  CreateNewUserRoute/form/index.js</span>\n<span class=\"token keyword\">import</span> React <span class=\"token keyword\">from</span> <span class=\"token string\">'react'</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> Formik<span class=\"token punctuation\">,</span> Form <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'formik'</span>\n<span class=\"token keyword\">import</span> NewUserSubForm <span class=\"token keyword\">from</span> <span class=\"token string\">'./subforms/NewUserSubForm'</span>\n<span class=\"token keyword\">import</span> validationSchema <span class=\"token keyword\">from</span> <span class=\"token string\">'./validationSchema'</span>\n<span class=\"token keyword\">import</span> defaultValues <span class=\"token keyword\">from</span> <span class=\"token string\">'./defaultValues'</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> <span class=\"token constant\">USER</span> <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'./fieldsNames'</span>\n<span class=\"token keyword\">import</span> ErrorBanner <span class=\"token keyword\">from</span> <span class=\"token string\">'path/to/components/ErrorBanner'</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">NewUserSubForm</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">React<span class=\"token punctuation\">.</span>Component</span> <span class=\"token punctuation\">{</span>\n  state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n    unknownErrors<span class=\"token operator\">:</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function-variable function\">onSubmit</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">values<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> setSubmitting<span class=\"token punctuation\">,</span> setErrors <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">try</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token comment\">//  Send values somehow</span>\n      <span class=\"token keyword\">await</span> <span class=\"token function\">sendForm</span><span class=\"token punctuation\">(</span>values<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">catch</span> <span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token comment\">//  Map and show the errors in your form</span>\n      <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>formErrors<span class=\"token punctuation\">,</span> unknownErrors<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">mapErrorsFromRequest</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">)</span>\n\n      <span class=\"token function\">setErrors</span><span class=\"token punctuation\">(</span>formErrors<span class=\"token punctuation\">)</span>\n      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n        unknownErrors<span class=\"token punctuation\">,</span>\n      <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">finally</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token function\">setSubmitting</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">false</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> unknownErrors <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state\n\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n      <span class=\"token operator\">&lt;</span>Formik onSubmit<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>onSubmit<span class=\"token punctuation\">}</span> initialValues<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>defaultValues<span class=\"token punctuation\">}</span> validationSchema<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>validationSchema<span class=\"token punctuation\">}</span><span class=\"token operator\">></span>\n        <span class=\"token punctuation\">{</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span>\n          <span class=\"token operator\">&lt;</span>Form<span class=\"token operator\">></span>\n            <span class=\"token punctuation\">{</span>unknownErrors <span class=\"token operator\">&amp;&amp;</span> <span class=\"token operator\">&lt;</span>ErrorBanner errors<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>unknownErrors<span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span><span class=\"token punctuation\">}</span>\n            <span class=\"token operator\">&lt;</span>NewUserSubForm namespace<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token constant\">USER</span><span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n          <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>Form<span class=\"token operator\">></span>\n        <span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span>\n      <span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>Formik<span class=\"token operator\">></span>\n    <span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>And that’s it! Of course, this is a very simple example, you could have different needs.</p>\n<h2>Helpful advices on creating subforms</h2>\n<p>I want to leave you with some advices that helped me while I was refactoring my codebase. It's good to have them in mind to ease the process of code refactoring.</p>\n<h3>A subform should have only first level values in its state</h3>\n<p>A subform should have only first level values in its state, which means that, when you design a subform, you shouldn’t get crazy about the shape of its values. It should be a flat object and every key should contain the field value.\nThis way it’s so much easier to write validations, default values and error handling (and why not, also the React component).</p>\n<p>You can avoid this advice <strong>only when you are using a subform into you subform</strong>. For example, let’s say you have an address subform. It has a lot of fields and a complex validation schema. In that scenario all the logic will be handled by the address subform and you’ll just need to orchestrate it in your own subform, just like you would do in the main form.</p>\n<h3>Keep the validation schema extensible and scalable</h3>\n<p>I didn’t do it in this article but the idea is to export a function instead of a schema. This function will accept parameters that will define the schema that you’ll get.\nIn this case you can toggle the “required” validation in some cases, or other kinds of validation.</p>\n<p><strong>Example</strong>: let’s say that we want to make the “lastName” field optional, but not always. That’s how you could define your schema:</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token comment\">//  UserSubform/validationSchema.js</span>\n<span class=\"token keyword\">import</span> <span class=\"token operator\">*</span> <span class=\"token keyword\">as</span> yup <span class=\"token keyword\">from</span> <span class=\"token string\">'yup'</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> <span class=\"token constant\">FIRST_NAME</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">LAST_NAME</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">EMAIL</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">PASSWORD</span> <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'./fieldsNames'</span>\n\n<span class=\"token keyword\">const</span> <span class=\"token constant\">MIN_PASSWORD_LENGTH</span> <span class=\"token operator\">=</span> <span class=\"token number\">8</span>\n\n<span class=\"token keyword\">const</span> <span class=\"token constant\">REQUIRED_MESSAGE</span> <span class=\"token operator\">=</span> <span class=\"token string\">'This field is required'</span>\n<span class=\"token keyword\">const</span> <span class=\"token constant\">INVALID_EMAIL_FORMAT</span> <span class=\"token operator\">=</span> <span class=\"token string\">'Invalid email format'</span>\n<span class=\"token keyword\">const</span> <span class=\"token constant\">PASSWORD_TOO_SHOWRT</span> <span class=\"token operator\">=</span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">The password must be long at least </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token constant\">MIN_PASSWORD_LENGTH</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\"> characters</span><span class=\"token template-punctuation string\">`</span></span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token keyword\">function</span> <span class=\"token function\">validationSchema</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">mandatoryFields <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> <span class=\"token punctuation\">[</span><span class=\"token constant\">LAST_NAME</span><span class=\"token punctuation\">]</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span> <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span> yup<span class=\"token punctuation\">.</span><span class=\"token function\">object</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n    <span class=\"token punctuation\">[</span><span class=\"token constant\">FIRST_NAME</span><span class=\"token punctuation\">]</span><span class=\"token operator\">:</span> yup<span class=\"token punctuation\">.</span><span class=\"token function\">string</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">required</span><span class=\"token punctuation\">(</span><span class=\"token constant\">REQUIRED_MESSAGE</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">[</span><span class=\"token constant\">LAST_NAME</span><span class=\"token punctuation\">]</span><span class=\"token operator\">:</span> yup<span class=\"token punctuation\">.</span><span class=\"token function\">lazy</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span>mandatoryFields<span class=\"token punctuation\">.</span>lastName <span class=\"token operator\">?</span> yup<span class=\"token punctuation\">.</span><span class=\"token function\">string</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">required</span><span class=\"token punctuation\">(</span><span class=\"token constant\">REQUIRED_MESSAGE</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> yup<span class=\"token punctuation\">.</span><span class=\"token function\">string</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">[</span><span class=\"token constant\">EMAIL</span><span class=\"token punctuation\">]</span><span class=\"token operator\">:</span> yup\n      <span class=\"token punctuation\">.</span><span class=\"token function\">string</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">.</span><span class=\"token function\">required</span><span class=\"token punctuation\">(</span><span class=\"token constant\">REQUIRED_MESSAGE</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">.</span><span class=\"token function\">email</span><span class=\"token punctuation\">(</span><span class=\"token constant\">INVALID_EMAIL_FORMAT</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">[</span><span class=\"token constant\">PASSWORD</span><span class=\"token punctuation\">]</span><span class=\"token operator\">:</span> yup\n      <span class=\"token punctuation\">.</span><span class=\"token function\">string</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">.</span><span class=\"token function\">required</span><span class=\"token punctuation\">(</span><span class=\"token constant\">REQUIRED_MESSAGE</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">.</span><span class=\"token function\">min</span><span class=\"token punctuation\">(</span><span class=\"token constant\">MIN_PASSWORD_LENGTH</span><span class=\"token punctuation\">,</span> <span class=\"token constant\">PASSWORD_TOO_SHOWRT</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Now you have a scalable validation schema.\nIn this way you can always decide if a certain field is required or not. Also, you can extend that function to add parameters. In this way, if your subform scales, you’ll just need to add parameters and adjust the code in the subform accordingly, but <strong>every single form that uses your subform won’t be affected by these changes because everything is retro compatible</strong>.</p>\n<h2>Conclusions</h2>\n<p>Dealing with forms is not easy. Of course, there are simple cases, but there are also trickier ones. This was my way to organize the code, and of course, it’s not perfect.\nI’m sure there are other thousands amazing ways to solve this problem better than this, but for now, this is the best way I’ve found to keep everything testable, maintainable and scalable.</p>\n<p>I hope this will help you, and if you have a better approach, I’m looking forward to reading it!\nUntil next time, happy hacking!</p>","fields":{"slug":"/the-concept-of-subforms-with-formik/","tags":["formik","forms","react","subforms"]}}}]}},"pageContext":{"slug":"/tags/formik","tag":"formik","categories":["Architecture","Coding","DevOps","Engineering","ProjectManagement","QA","Social","TechRadar"]}}