{"id":29232,"date":"2024-08-08T10:04:27","date_gmt":"2024-08-08T08:04:27","guid":{"rendered":"https:\/\/www.codemotion.com\/magazine\/?p=29232"},"modified":"2024-08-08T10:04:27","modified_gmt":"2024-08-08T08:04:27","slug":"building-reusable-multiple-step-form-in-reactjs","status":"publish","type":"post","link":"https:\/\/www.codemotion.com\/magazine\/frontend\/building-reusable-multiple-step-form-in-reactjs\/","title":{"rendered":"Building reusable multiple-step form in ReactJS"},"content":{"rendered":"\n<p><strong>Introduction<\/strong><\/p>\n\n\n\n<p>Building user-friendly multiple-step forms in <a href=\"https:\/\/www.codemotion.com\/magazine\/languages\/a-complete-introduction-to-the-react-library\/\">ReactJS<\/a> can be challenging. Developers often struggle with managing form states, ensuring seamless user navigation, handling validation, and maintaining a smooth user experience. Adhering to best practices is necessary for these forms to become cumbersome, leading to user frustration and increased abandonment rates.<\/p>\n\n\n\n<p>In this article, I provide a comprehensive guide to best practices for building multiple-step forms in ReactJS. I outline practical strategies for state management, user flow control, and validation techniques. By adhering to these guidelines, you can create intuitive and efficient multi-step forms.<\/p>\n\n\n\n<p><strong>Prerequisites<\/strong><\/p>\n\n\n\n<p>To follow along with this guide, you should have a basic understanding of:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>ReactJS and its core concepts (components, props, state)<\/li>\n\n\n\n<li>JavaScript ES6 syntax<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-directory-structure\"><strong>Directory structure<\/strong><\/h2>\n\n\n\n<p>We will create a directory structure that looks like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">src\/<br>|-- components\/<br>|   |-- Button\/<br>|   |-- Icon\/<br>|-- containers\/ <br>|   |-- StepsController\/<br>|   |   |-- StepsController.js<br>|   |   |-- StepsIndicator.js<br>|   |   |-- StepsController.module.scss<br>|   |-- Form\/ <br>|   |   |-- FirstStep.js<br>|   |   |-- SecondStep.js<br>|   |   |-- ThirdStep.js<br>|   |   |-- Form.js<br>|   |   |-- Form.module.scss<br>|-- icons\/<br>    |--checked.svg<br>|-- services\/<br>|   |--manageValidation.js<br>|-- App.js<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-creating-the-form-component\"><strong>Creating the Form component<\/strong><\/h4>\n\n\n\n<p>The Form component will control the form state and pass each step component to the StepsController. Each step of the form will be a separate component. The Form component handles validation logic, field changes, and submission.<\/p>\n\n\n\n<p><strong>Form.js&nbsp;<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> React, { useState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> StepsController <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/StepsController\/StepsController\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> FirstStep <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/FirstStep\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> SecondStep <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/SecondStep'<\/span>\n<span class=\"hljs-keyword\">import<\/span> ThirdStep <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/ThirdStep'<\/span>\n<span class=\"hljs-keyword\">import<\/span> { checkIsValidFormSteps, updateErrorsFormSteps } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/..\/services\/manageValidation\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> styles <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/Form.module.scss\"<\/span>;\n\n\n<span class=\"hljs-keyword\">const<\/span> SpotForm = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n   <span class=\"hljs-keyword\">const<\/span> &#91;validationError, setValidationError] = useState(&#91;]);\n   <span class=\"hljs-keyword\">const<\/span> &#91;formData, setFormData] = useState({\n       <span class=\"hljs-attr\">name<\/span>: <span class=\"hljs-string\">''<\/span>,\n       <span class=\"hljs-attr\">website<\/span>: <span class=\"hljs-string\">''<\/span>,\n       <span class=\"hljs-attr\">address<\/span>: <span class=\"hljs-string\">''<\/span>,\n       <span class=\"hljs-attr\">email<\/span>: <span class=\"hljs-string\">''<\/span>,\n       <span class=\"hljs-attr\">description<\/span>: <span class=\"hljs-string\">''<\/span>,\n       <span class=\"hljs-attr\">foundationDate<\/span>: <span class=\"hljs-string\">''<\/span>\n   });\n   <span class=\"hljs-keyword\">const<\/span> handleFieldChange = <span class=\"hljs-function\">(<span class=\"hljs-params\">name, value, isRequired<\/span>) =&gt;<\/span> {\n       setFormData({ ...formData, &#91;name]: value })\n       isRequired &amp;&amp; setValidationError(\n           validationError.filter(<span class=\"hljs-function\">(<span class=\"hljs-params\">errorItem<\/span>) =&gt;<\/span> errorItem !== name)\n       )\n   }\n   <span class=\"hljs-keyword\">const<\/span> manageNextStepValidation = <span class=\"hljs-function\">(<span class=\"hljs-params\">step<\/span>) =&gt;<\/span> {\n       <span class=\"hljs-keyword\">const<\/span> isValid = checkIsValidFormSteps({ formData, step });\n       <span class=\"hljs-keyword\">if<\/span> (!isValid) {\n           updateErrorsFormSteps({\n               formData,\n               step,\n               setValidationError\n           });\n           <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">false<\/span>\n       }\n       <span class=\"hljs-keyword\">if<\/span> (step === <span class=\"hljs-number\">3<\/span> &amp;&amp; isValid) {\n           handleSubmit()\n       }\n       <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">true<\/span>\n   }\n   <span class=\"hljs-keyword\">const<\/span> handleSubmit = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n       alert(<span class=\"hljs-string\">\"The form is valid. You can now submit the data: to the server.\"<\/span>)\n   };\n   <span class=\"hljs-keyword\">const<\/span> steps = &#91;\n       <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">FirstStep<\/span> <span class=\"hljs-attr\">formData<\/span>=<span class=\"hljs-string\">{formData}<\/span> <span class=\"hljs-attr\">validationError<\/span>=<span class=\"hljs-string\">{validationError}<\/span> <span class=\"hljs-attr\">handleFieldChange<\/span>=<span class=\"hljs-string\">{handleFieldChange}<\/span> \/&gt;<\/span><\/span>,\n       &lt;SecondStep formData={formData} validationError={validationError} handleFieldChange={handleFieldChange} \/&gt;,\n       &lt;ThirdStep formData={formData} validationError={validationError} handleFieldChange={handleFieldChange} \/&gt;\n   ]\n   <span class=\"hljs-keyword\">return<\/span> (\n       <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.container}<\/span>&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">StepsController<\/span>\n               <span class=\"hljs-attr\">formTitle<\/span>=<span class=\"hljs-string\">\"Add a new company\"<\/span>\n               <span class=\"hljs-attr\">manageNextStepValidation<\/span>=<span class=\"hljs-string\">{manageNextStepValidation}<\/span>\n               <span class=\"hljs-attr\">steps<\/span>=<span class=\"hljs-string\">{steps}<\/span>\n               <span class=\"hljs-attr\">stepsAmount<\/span>=<span class=\"hljs-string\">{3}<\/span>\n           \/&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n   )\n};\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> SpotForm;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id=\"h-creating-step-components\"><strong>Creating step components<\/strong><\/h2>\n\n\n\n<p>Step components are stateless; they receive formData, handleFieldChange, and validationError as props from the Form component. In this example, I use the Input component from \u201creactstrap\u201d.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-firststep-js-nbsp\"><strong>FirstStep.js&nbsp;<\/strong><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> React <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react'<\/span>\n<span class=\"hljs-keyword\">import<\/span> cx <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"classnames\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { Input } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'reactstrap'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> styles <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/Form.module.scss'<\/span>\n\n\n<span class=\"hljs-keyword\">const<\/span> FirstStep = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ validationError, formData, handleFieldChange }<\/span>) =&gt;<\/span> {\n\n\n   <span class=\"hljs-keyword\">return<\/span> (\n       <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.container}<\/span>&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.title}<\/span>&gt;<\/span>General<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h2<\/span>&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.formItem}<\/span>&gt;<\/span>\n               <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.fieldLabel}<\/span> <span class=\"hljs-attr\">htmlFor<\/span>=<span class=\"hljs-string\">\"name\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">span<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.asterisk}<\/span>&gt;<\/span>*<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">span<\/span>&gt;<\/span> company name<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n               <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Input<\/span>\n                   <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"name\"<\/span>\n                   <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"name\"<\/span>\n                   <span class=\"hljs-attr\">placeholder<\/span>=<span class=\"hljs-string\">\"Company name\"<\/span>\n                   <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">{formData.name}<\/span>\n                   <span class=\"hljs-attr\">onChange<\/span>=<span class=\"hljs-string\">{(event)<\/span> =&gt;<\/span> {\n                       handleFieldChange(\"name\", event.target.value, true)\n                   }}\n                   className={cx(styles.input, {\n                       &#91;styles.inputError]: validationError.includes(\"name\"),\n                   })}\n               \/&gt;\n           <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.textareaContainer}<\/span>&gt;<\/span>\n               <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.fieldLabel}<\/span> <span class=\"hljs-attr\">htmlFor<\/span>=<span class=\"hljs-string\">\"text\"<\/span>&gt;<\/span>description<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n               <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Input<\/span>\n                   <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"text\"<\/span>\n                   <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"text\"<\/span>\n                   <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{cx(styles.textarea,<\/span> {\n                       &#91;<span class=\"hljs-attr\">styles.inputError<\/span>]<span class=\"hljs-attr\">:<\/span> <span class=\"hljs-attr\">validationError.includes<\/span>(\"<span class=\"hljs-attr\">description<\/span>\"),\n                   })}\n                   <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"textarea\"<\/span>\n                   <span class=\"hljs-attr\">placeholder<\/span>=<span class=\"hljs-string\">\"Description\"<\/span>\n                   <span class=\"hljs-attr\">onChange<\/span>=<span class=\"hljs-string\">{(event)<\/span> =&gt;<\/span> {\n                       handleFieldChange(\"description\", event.target.value)\n                   }}\n                   value={formData.description}\n               \/&gt;\n           <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span> &gt;<\/span>\n   )\n}\n\n\nexport default FirstStep\n<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id=\"h-secondstep-js\"><strong>SecondStep.js<\/strong><\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> React <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react'<\/span>\n<span class=\"hljs-keyword\">import<\/span> cx <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"classnames\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { Input } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'reactstrap'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> styles <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/Form.module.scss'<\/span>\n<span class=\"hljs-keyword\">const<\/span> SecondStep = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ validationError, formData, handleFieldChange }<\/span>) =&gt;<\/span> {\n   <span class=\"hljs-keyword\">return<\/span> (\n       <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.container}<\/span>&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.title}<\/span>&gt;<\/span>Details<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h2<\/span>&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.formItem}<\/span>&gt;<\/span>\n               <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.fieldLabel}<\/span> <span class=\"hljs-attr\">htmlFor<\/span>=<span class=\"hljs-string\">\"website\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">span<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.asterisk}<\/span>&gt;<\/span>*<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">span<\/span>&gt;<\/span> website<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n               <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Input<\/span>\n                   <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"website\"<\/span>\n                   <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"website\"<\/span>\n                   <span class=\"hljs-attr\">placeholder<\/span>=<span class=\"hljs-string\">\"https:\/\/company.com\"<\/span>\n                   <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">{formData.website}<\/span>\n                   <span class=\"hljs-attr\">onChange<\/span>=<span class=\"hljs-string\">{(event)<\/span> =&gt;<\/span> {\n                       handleFieldChange(\"website\", event.target.value, true)\n                   }}\n                   className={cx(styles.input, {\n                       &#91;styles.inputError]: validationError.includes(\"website\"),\n                   })}\n               \/&gt;\n           <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{cx(styles.formItem)}<\/span>&gt;<\/span>\n               <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.fieldLabel}<\/span> <span class=\"hljs-attr\">htmlFor<\/span>=<span class=\"hljs-string\">\"address\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">span<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.asterisk}<\/span>&gt;<\/span>*<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">span<\/span>&gt;<\/span> address<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span> &gt;<\/span>\n               <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Input<\/span>\n                   <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"address\"<\/span>\n                   <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"address\"<\/span>\n                   <span class=\"hljs-attr\">placeholder<\/span>=<span class=\"hljs-string\">\"Address\"<\/span>\n                   <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">{formData.address}<\/span>\n                   <span class=\"hljs-attr\">onChange<\/span>=<span class=\"hljs-string\">{(event)<\/span> =&gt;<\/span> {\n                       handleFieldChange(\"address\", event.target.value, true)\n                   }}\n                   className={cx(styles.input, {\n                       &#91;styles.inputError]: validationError.includes(\"address\"),\n                   })}\n               \/&gt;\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n   )\n}\nexport default SecondStep\n<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\" id=\"h-thirdstep-js\"><strong>ThirdStep.js<\/strong><br><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> React <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react'<\/span>\n<span class=\"hljs-keyword\">import<\/span> cx <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"classnames\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { Input } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'reactstrap'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> styles <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/Form.module.scss'<\/span>\n<span class=\"hljs-keyword\">const<\/span> ThirdStep = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ validationError, formData, handleFieldChange }<\/span>) =&gt;<\/span> {\n   <span class=\"hljs-keyword\">return<\/span> (\n       <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.container}<\/span>&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.title}<\/span>&gt;<\/span>Additional<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h2<\/span>&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.formItem}<\/span>&gt;<\/span>\n               <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.fieldLabel}<\/span> <span class=\"hljs-attr\">htmlFor<\/span>=<span class=\"hljs-string\">\"email\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">span<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.asterisk}<\/span>&gt;<\/span>*<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">span<\/span>&gt;<\/span> email<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n               <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Input<\/span>\n                   <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"email\"<\/span>\n                   <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"email\"<\/span>\n                   <span class=\"hljs-attr\">placeholder<\/span>=<span class=\"hljs-string\">\"name@company.com\"<\/span>\n                   <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">{formData.email}<\/span>\n                   <span class=\"hljs-attr\">onChange<\/span>=<span class=\"hljs-string\">{(event)<\/span> =&gt;<\/span> {\n                       handleFieldChange(\"email\", event.target.value, true)\n                   }}\n                   className={cx(styles.input, {\n                       &#91;styles.inputError]: validationError.includes(\"email\"),\n                   })} \/&gt;\n           <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{cx(styles.formItem)}<\/span>&gt;<\/span>\n               <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.fieldLabel}<\/span> <span class=\"hljs-attr\">htmlFor<\/span>=<span class=\"hljs-string\">\"foundationDate\"<\/span>&gt;<\/span>Foundation date <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n               <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Input<\/span>\n                   <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"foundationDate\"<\/span>\n                   <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"foundationDate\"<\/span>\n                   <span class=\"hljs-attr\">placeholder<\/span>=<span class=\"hljs-string\">\"10\/24\/2015 (MM\/DD\/YYYY)\"<\/span>\n                   <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">{formData.foundationDate}<\/span>\n                   <span class=\"hljs-attr\">onChange<\/span>=<span class=\"hljs-string\">{(event)<\/span> =&gt;<\/span> {\n                       handleFieldChange(\"foundationDate\", event.target.value)\n                   }}\n                   className={styles.input}\n               \/&gt;\n           <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n   )\n}\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> ThirdStep\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\"><strong>Creating the StepsController component<\/strong><\/h2>\n\n\n\n<p>The StepsController component handles navigation between steps. It controls the steps&#8217; state and manages navigation between them. It receives the steps components, a function to check if a step is valid, the number of steps, and the form title as props. This structure allows us to reuse StepsController in different forms.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-stepscontroller-js\"><strong>StepsController.js<\/strong><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> React, { useState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> Button <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/..\/components\/Button\/Button\"<\/span>\n<span class=\"hljs-keyword\">import<\/span> StepsIndicator <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/StepsIndicator\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> styles <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/StepsController.module.scss\"<\/span>;\n\n\n<span class=\"hljs-keyword\">const<\/span> StepsController = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ steps, manageNextStepValidation, stepsAmount, formTitle }<\/span>) =&gt;<\/span> {\n   <span class=\"hljs-keyword\">const<\/span> &#91;step, setStep] = useState(<span class=\"hljs-number\">1<\/span>);\n   <span class=\"hljs-keyword\">const<\/span> onNextStep = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n       <span class=\"hljs-keyword\">if<\/span> (manageNextStepValidation(step) &amp;&amp; step !== stepsAmount) {\n           setStep(step + <span class=\"hljs-number\">1<\/span>)\n       }\n   }\n   <span class=\"hljs-keyword\">return<\/span> (\n       <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.container}<\/span>&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.indicatorContainer}<\/span>&gt;<\/span>\n               <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.title}<\/span>&gt;<\/span>{formTitle}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n               <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">StepsIndicator<\/span> <span class=\"hljs-attr\">step<\/span>=<span class=\"hljs-string\">{step}<\/span> <span class=\"hljs-attr\">stepsAmount<\/span>=<span class=\"hljs-string\">{stepsAmount}<\/span> \/&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.formContainer}<\/span>&gt;<\/span>\n               <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span> {\n                   steps&#91;step - 1]\n               }<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n               <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.buttonsContainer}<\/span>&gt;<\/span>\n                   <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Button<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.nextButton}<\/span> <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> onNextStep()}&gt;{step !== stepsAmount ? \"Next\" : \"Send\"}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Button<\/span>&gt;<\/span>\n                   {step !== 1 &amp;&amp; <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Button<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.backButton}<\/span> <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> setStep(step - 1)}&gt;Back<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Button<\/span>&gt;<\/span>}\n               <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n       <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n   )\n};\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> StepsController;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\" id=\"h-stepindicator-js\"><strong>StepIndicator.js<\/strong><\/h3>\n\n\n\n<p>The StepsIndicator component displays the current step to the user. It is a stateless component that receives the current step and the total number of steps as props. In this example, the steps indicator is displayed only for screens wider than 872px. For mobile screens, you might want to change the design and possibly use a different steps indicator component.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> React <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> cx <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"classnames\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> Icon <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/..\/components\/Icon\/Icon\"<\/span>;\n<span class=\"hljs-keyword\">import<\/span> CheckedIcon <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'..\/..\/icons\/checked.svg'<\/span>\n<span class=\"hljs-keyword\">import<\/span> styles <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/StepsController.module.scss\"<\/span>;\n\n\n<span class=\"hljs-keyword\">const<\/span> StepsIndicator = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ step, stepsAmount }<\/span>) =&gt;<\/span> {\n   <span class=\"hljs-keyword\">const<\/span> getStepsIndicator = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n       <span class=\"hljs-keyword\">const<\/span> stepsAmountArray = &#91;]\n       <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">let<\/span> i = <span class=\"hljs-number\">1<\/span>; i &lt;= stepsAmount; i++) {\n           stepsAmountArray.push(i)\n       }\n       <span class=\"hljs-keyword\">return<\/span> stepsAmountArray\n   }\n   <span class=\"hljs-keyword\">return<\/span> (\n       <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.stepsContainer}<\/span>&gt;<\/span>\n           {getStepsIndicator().map(item =&gt; <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.step}<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{item}<\/span>&gt;<\/span>\n               <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{styles.circleContainer}<\/span> &gt;<\/span>\n                   {item &gt; 1 &amp;&amp; <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{cx(styles.stem,<\/span> {\n                       &#91;<span class=\"hljs-attr\">styles.stemActive<\/span>]<span class=\"hljs-attr\">:<\/span> <span class=\"hljs-attr\">item<\/span> === <span class=\"hljs-string\">step<\/span> || <span class=\"hljs-attr\">step<\/span> &gt;<\/span> item\n                   })}&gt;<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>}\n                   <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{cx(styles.circle,<\/span> {\n                       &#91;<span class=\"hljs-attr\">styles.circleActive<\/span>]<span class=\"hljs-attr\">:<\/span> <span class=\"hljs-attr\">item<\/span> === <span class=\"hljs-string\">step<\/span> || <span class=\"hljs-attr\">step<\/span> &gt;<\/span> item\n                   })}&gt;\n                       {step &gt; item ? <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Icon<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">{CheckedIcon}<\/span> \/&gt;<\/span> : <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{cx(styles.circleIn,<\/span> {\n                           &#91;<span class=\"hljs-attr\">styles.circleInActive<\/span>]<span class=\"hljs-attr\">:<\/span> <span class=\"hljs-attr\">item<\/span> === <span class=\"hljs-string\">step<\/span> || <span class=\"hljs-attr\">step<\/span> &gt;<\/span> item\n                       })}&gt;<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>}\n                   <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n               <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n           )}\n       <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n   )\n};\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> StepsIndicator;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\" id=\"h-form-validation\"><strong>Form validation<\/strong><\/h3>\n\n\n\n<p>In this example, custom form validation is used for more flexibility and control. You can also use packages like Formik or Yup to validate the form.<\/p>\n\n\n\n<p><strong>manageValidation.js<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">const<\/span> validateEmail = <span class=\"hljs-function\">(<span class=\"hljs-params\">email<\/span>) =&gt;<\/span> {\n <span class=\"hljs-keyword\">const<\/span> re = <span class=\"hljs-regexp\">\/^((&#91;^&lt;&gt;()&#91;\\]\\\\.,;:\\s@\"]+(\\.&#91;^&lt;&gt;()&#91;\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\&#91;&#91;0-9]{1,3}\\.&#91;0-9]{1,3}\\.&#91;0-9]{1,3}\\.&#91;0-9]{1,3}\\])|((&#91;a-zA-Z\\-0-9]+\\.)+&#91;a-zA-Z]{2,}))$\/<\/span>;\n <span class=\"hljs-keyword\">return<\/span> re.test(<span class=\"hljs-built_in\">String<\/span>(email).toLowerCase());\n}\n<span class=\"hljs-keyword\">const<\/span> getErrors = <span class=\"hljs-function\">(<span class=\"hljs-params\">state, keys<\/span>) =&gt;<\/span> {\n <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-built_in\">Object<\/span>.entries(state)\n   .filter(<span class=\"hljs-function\">(<span class=\"hljs-params\">&#91;key]<\/span>) =&gt;<\/span> keys.includes(key))\n   .filter(<span class=\"hljs-function\">(<span class=\"hljs-params\">&#91;key, value]<\/span>) =&gt;<\/span>\n     key === <span class=\"hljs-string\">\"email\"<\/span> ? !validateEmail(value) : !value?.length\n   )\n   .map(<span class=\"hljs-function\">(<span class=\"hljs-params\">&#91;key]<\/span>) =&gt;<\/span> key);\n}\n<span class=\"hljs-keyword\">const<\/span> cancelValidationError = (\n filterType,\n setValidationError,\n validationError\n) =&gt; {\n\n\n setValidationError(\n   validationError.filter(<span class=\"hljs-function\">(<span class=\"hljs-params\">errorItem<\/span>) =&gt;<\/span> errorItem !== filterType)\n );\n};\n<span class=\"hljs-keyword\">const<\/span> checkIsValidFormSteps = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ formData, step }<\/span>) =&gt;<\/span> {\n <span class=\"hljs-keyword\">const<\/span> {\n   name,\n   address,\n   website,\n   email\n } = formData;\n\n\n <span class=\"hljs-keyword\">if<\/span> (step === <span class=\"hljs-number\">1<\/span>) {\n   <span class=\"hljs-keyword\">return<\/span> !!(name)\n }\n <span class=\"hljs-keyword\">if<\/span> (step === <span class=\"hljs-number\">2<\/span>) {\n   <span class=\"hljs-keyword\">return<\/span> !!(address &amp;&amp; website)\n }\n <span class=\"hljs-keyword\">if<\/span> (step === <span class=\"hljs-number\">3<\/span>) {\n   <span class=\"hljs-keyword\">return<\/span> !!(validateEmail(email))\n }\n}\n<span class=\"hljs-keyword\">const<\/span> updateErrorsFormSteps = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ formData, setValidationError, step }<\/span>) =&gt;<\/span> {\n <span class=\"hljs-keyword\">if<\/span> (step === <span class=\"hljs-number\">1<\/span>) {\n   <span class=\"hljs-keyword\">const<\/span> errors = getErrors(formData, &#91;<span class=\"hljs-string\">\"name\"<\/span>]);\n   setValidationError(errors);\n }\n <span class=\"hljs-keyword\">if<\/span> (step === <span class=\"hljs-number\">2<\/span>) {\n   <span class=\"hljs-keyword\">const<\/span> errors = getErrors(formData, &#91;<span class=\"hljs-string\">\"website\"<\/span>, <span class=\"hljs-string\">\"address\"<\/span>]);\n   setValidationError(errors);\n }\n <span class=\"hljs-keyword\">if<\/span> (step === <span class=\"hljs-number\">3<\/span>) {\n   <span class=\"hljs-keyword\">const<\/span> errors = getErrors(formData, &#91;<span class=\"hljs-string\">\"email\"<\/span>]);\n   setValidationError(errors);\n }\n};\n<span class=\"hljs-keyword\">export<\/span> {\n cancelValidationError,\n checkIsValidFormSteps,\n updateErrorsFormSteps\n};\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h2>\n\n\n\n<p>By following these steps, you&#8217;ve created a reusable multiple-step form in ReactJS. This approach allows you to manage form data efficiently, navigate between form steps, and enhance the user experience by breaking down complex forms into more straightforward, manageable parts.<\/p>\n\n\n\n<p>You can find the <a href=\"https:\/\/github.com\/NataliaGon\/multistep\">full code on GitHub<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Building user-friendly multiple-step forms in ReactJS can be challenging. Developers often struggle with managing form states, ensuring seamless user navigation, handling validation, and maintaining a smooth user experience. Adhering to best practices is necessary for these forms to become cumbersome, leading to user frustration and increased abandonment rates. In this article, I provide a&#8230; <a class=\"more-link\" href=\"https:\/\/www.codemotion.com\/magazine\/frontend\/building-reusable-multiple-step-form-in-reactjs\/\">Read more<\/a><\/p>\n","protected":false},"author":290,"featured_media":21192,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","_uag_custom_page_level_css":"","_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","footnotes":""},"categories":[6],"tags":[12486,12488,54,12067],"collections":[],"class_list":{"0":"post-29232","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-frontend","8":"tag-form","9":"tag-guide","10":"tag-react","11":"tag-tutorial","12":"entry"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.9 (Yoast SEO v27.5) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Building reusable multiple-step form in ReactJS - Codemotion Magazine<\/title>\n<meta name=\"description\" content=\"A comprehensive guide to best practices for building multiple-step forms in ReactJS. Code included, read on!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.codemotion.com\/magazine\/frontend\/building-reusable-multiple-step-form-in-reactjs\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Building reusable multiple-step form in ReactJS\" \/>\n<meta property=\"og:description\" content=\"A comprehensive guide to best practices for building multiple-step forms in ReactJS. Code included, read on!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.codemotion.com\/magazine\/frontend\/building-reusable-multiple-step-form-in-reactjs\/\" \/>\n<meta property=\"og:site_name\" content=\"Codemotion Magazine\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Codemotion.Italy\/\" \/>\n<meta property=\"article:published_time\" content=\"2024-08-08T08:04:27+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1196\" \/>\n\t<meta property=\"og:image:height\" content=\"876\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Noa Shtang\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:site\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Noa Shtang\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/building-reusable-multiple-step-form-in-reactjs\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/building-reusable-multiple-step-form-in-reactjs\\\/\"},\"author\":{\"name\":\"Noa Shtang\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#\\\/schema\\\/person\\\/42eec594b4990fd7844117812bace211\"},\"headline\":\"Building reusable multiple-step form in ReactJS\",\"datePublished\":\"2024-08-08T08:04:27+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/building-reusable-multiple-step-form-in-reactjs\\\/\"},\"wordCount\":412,\"publisher\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/building-reusable-multiple-step-form-in-reactjs\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2023\\\/06\\\/React-Image.jpg\",\"keywords\":[\"form\",\"guide\",\"React\",\"tutorial\"],\"articleSection\":[\"Frontend\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/building-reusable-multiple-step-form-in-reactjs\\\/\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/building-reusable-multiple-step-form-in-reactjs\\\/\",\"name\":\"Building reusable multiple-step form in ReactJS - Codemotion Magazine\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/building-reusable-multiple-step-form-in-reactjs\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/building-reusable-multiple-step-form-in-reactjs\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2023\\\/06\\\/React-Image.jpg\",\"datePublished\":\"2024-08-08T08:04:27+00:00\",\"description\":\"A comprehensive guide to best practices for building multiple-step forms in ReactJS. Code included, read on!\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/building-reusable-multiple-step-form-in-reactjs\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/building-reusable-multiple-step-form-in-reactjs\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/building-reusable-multiple-step-form-in-reactjs\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2023\\\/06\\\/React-Image.jpg\",\"contentUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2023\\\/06\\\/React-Image.jpg\",\"width\":1196,\"height\":876,\"caption\":\"React native mobile app abstract concept vector illustration. Cross-platform native mobile app development framework, JavaScript library, user interface, operating system abstract metaphor.\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/building-reusable-multiple-step-form-in-reactjs\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Frontend\",\"item\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/frontend\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Building reusable multiple-step form in ReactJS\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#website\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/\",\"name\":\"Codemotion Magazine\",\"description\":\"We code the future. Together\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#organization\",\"name\":\"Codemotion\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/codemotionlogo.png\",\"contentUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/codemotionlogo.png\",\"width\":225,\"height\":225,\"caption\":\"Codemotion\"},\"image\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/Codemotion.Italy\\\/\",\"https:\\\/\\\/x.com\\\/CodemotionIT\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#\\\/schema\\\/person\\\/42eec594b4990fd7844117812bace211\",\"name\":\"Noa Shtang\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2024\\\/08\\\/noah1-100x100.jpg\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2024\\\/08\\\/noah1-100x100.jpg\",\"contentUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2024\\\/08\\\/noah1-100x100.jpg\",\"caption\":\"Noa Shtang\"},\"sameAs\":[\"http:\\\/\\\/asasda\"],\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/author\\\/noah-shtang\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Building reusable multiple-step form in ReactJS - Codemotion Magazine","description":"A comprehensive guide to best practices for building multiple-step forms in ReactJS. Code included, read on!","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.codemotion.com\/magazine\/frontend\/building-reusable-multiple-step-form-in-reactjs\/","og_locale":"en_US","og_type":"article","og_title":"Building reusable multiple-step form in ReactJS","og_description":"A comprehensive guide to best practices for building multiple-step forms in ReactJS. Code included, read on!","og_url":"https:\/\/www.codemotion.com\/magazine\/frontend\/building-reusable-multiple-step-form-in-reactjs\/","og_site_name":"Codemotion Magazine","article_publisher":"https:\/\/www.facebook.com\/Codemotion.Italy\/","article_published_time":"2024-08-08T08:04:27+00:00","og_image":[{"width":1196,"height":876,"url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image.jpg","type":"image\/jpeg"}],"author":"Noa Shtang","twitter_card":"summary_large_image","twitter_creator":"@CodemotionIT","twitter_site":"@CodemotionIT","twitter_misc":{"Written by":"Noa Shtang","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/building-reusable-multiple-step-form-in-reactjs\/#article","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/building-reusable-multiple-step-form-in-reactjs\/"},"author":{"name":"Noa Shtang","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/42eec594b4990fd7844117812bace211"},"headline":"Building reusable multiple-step form in ReactJS","datePublished":"2024-08-08T08:04:27+00:00","mainEntityOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/building-reusable-multiple-step-form-in-reactjs\/"},"wordCount":412,"publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/building-reusable-multiple-step-form-in-reactjs\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image.jpg","keywords":["form","guide","React","tutorial"],"articleSection":["Frontend"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/building-reusable-multiple-step-form-in-reactjs\/","url":"https:\/\/www.codemotion.com\/magazine\/frontend\/building-reusable-multiple-step-form-in-reactjs\/","name":"Building reusable multiple-step form in ReactJS - Codemotion Magazine","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/building-reusable-multiple-step-form-in-reactjs\/#primaryimage"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/building-reusable-multiple-step-form-in-reactjs\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image.jpg","datePublished":"2024-08-08T08:04:27+00:00","description":"A comprehensive guide to best practices for building multiple-step forms in ReactJS. Code included, read on!","breadcrumb":{"@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/building-reusable-multiple-step-form-in-reactjs\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.codemotion.com\/magazine\/frontend\/building-reusable-multiple-step-form-in-reactjs\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/building-reusable-multiple-step-form-in-reactjs\/#primaryimage","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image.jpg","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image.jpg","width":1196,"height":876,"caption":"React native mobile app abstract concept vector illustration. Cross-platform native mobile app development framework, JavaScript library, user interface, operating system abstract metaphor."},{"@type":"BreadcrumbList","@id":"https:\/\/www.codemotion.com\/magazine\/frontend\/building-reusable-multiple-step-form-in-reactjs\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.codemotion.com\/magazine\/"},{"@type":"ListItem","position":2,"name":"Frontend","item":"https:\/\/www.codemotion.com\/magazine\/frontend\/"},{"@type":"ListItem","position":3,"name":"Building reusable multiple-step form in ReactJS"}]},{"@type":"WebSite","@id":"https:\/\/www.codemotion.com\/magazine\/#website","url":"https:\/\/www.codemotion.com\/magazine\/","name":"Codemotion Magazine","description":"We code the future. Together","publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.codemotion.com\/magazine\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.codemotion.com\/magazine\/#organization","name":"Codemotion","url":"https:\/\/www.codemotion.com\/magazine\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","width":225,"height":225,"caption":"Codemotion"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Codemotion.Italy\/","https:\/\/x.com\/CodemotionIT"]},{"@type":"Person","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/42eec594b4990fd7844117812bace211","name":"Noa Shtang","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/08\/noah1-100x100.jpg","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/08\/noah1-100x100.jpg","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/08\/noah1-100x100.jpg","caption":"Noa Shtang"},"sameAs":["http:\/\/asasda"],"url":"https:\/\/www.codemotion.com\/magazine\/author\/noah-shtang\/"}]}},"featured_image_src":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image-600x400.jpg","featured_image_src_square":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image-600x600.jpg","author_info":{"display_name":"Noa Shtang","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/noah-shtang\/"},"uagb_featured_image_src":{"full":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image.jpg",1196,876,false],"thumbnail":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image-150x150.jpg",150,150,true],"medium":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image-300x220.jpg",300,220,true],"medium_large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image-768x563.jpg",768,563,true],"large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image-1024x750.jpg",1024,750,true],"1536x1536":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image.jpg",1196,876,false],"2048x2048":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image.jpg",1196,876,false],"small-home-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image.jpg",100,73,false],"sidebar-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image-180x128.jpg",180,128,true],"genesis-singular-images":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image-896x504.jpg",896,504,true],"archive-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image-400x225.jpg",400,225,true],"gb-block-post-grid-landscape":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image-600x400.jpg",600,400,true],"gb-block-post-grid-square":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2023\/06\/React-Image-600x600.jpg",600,600,true]},"uagb_author_info":{"display_name":"Noa Shtang","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/noah-shtang\/"},"uagb_comment_info":0,"uagb_excerpt":"Introduction Building user-friendly multiple-step forms in ReactJS can be challenging. Developers often struggle with managing form states, ensuring seamless user navigation, handling validation, and maintaining a smooth user experience. Adhering to best practices is necessary for these forms to become cumbersome, leading to user frustration and increased abandonment rates. In this article, I provide a&#8230;&hellip;","lang":"en","_links":{"self":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/29232","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/users\/290"}],"replies":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/comments?post=29232"}],"version-history":[{"count":3,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/29232\/revisions"}],"predecessor-version":[{"id":29237,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/29232\/revisions\/29237"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media\/21192"}],"wp:attachment":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media?parent=29232"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/categories?post=29232"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/tags?post=29232"},{"taxonomy":"collections","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/collections?post=29232"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}