<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Antolin B. Bernas Jr.</title>
    <description>The latest articles on DEV Community by Antolin B. Bernas Jr. (@bernasantolin).</description>
    <link>https://dev.to/bernasantolin</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F475604%2F828763b5-ffc6-490a-862f-3fcf2ea93a85.jpeg</url>
      <title>DEV Community: Antolin B. Bernas Jr.</title>
      <link>https://dev.to/bernasantolin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bernasantolin"/>
    <language>en</language>
    <item>
      <title>Using setErrors for with Formik DOM, useFormikContext</title>
      <dc:creator>Antolin B. Bernas Jr.</dc:creator>
      <pubDate>Wed, 27 Oct 2021 18:22:20 +0000</pubDate>
      <link>https://dev.to/bernasantolin/using-seterrors-for-with-formik-dom-useformikcontext-5hgk</link>
      <guid>https://dev.to/bernasantolin/using-seterrors-for-with-formik-dom-useformikcontext-5hgk</guid>
      <description>&lt;p&gt;TL;DR Hi! everyone in this article I would like to share you about using of &lt;strong&gt;setErrors&lt;/strong&gt; within the Formik DOM, this is for everyone who struggling 😫😫 of setting an error messages from the backend request.&lt;/p&gt;

&lt;p&gt;In this scenario, I used &lt;strong&gt;useField&lt;/strong&gt; for separating of Fields from Form&lt;/p&gt;

&lt;p&gt;Follow this proceedures step by step 😊&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.)&lt;/strong&gt; First of all, make sure you have installed the following dependencies.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Formik
npm install Formik --save

Yup
npm install Formik --save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;2.)&lt;/strong&gt; Second, Create a component for custom formik as HOC&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fidp5bb1v3zfs9azlw6vo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fidp5bb1v3zfs9azlw6vo.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.)&lt;/strong&gt; Third, follow this code:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.1.)&lt;/strong&gt; Import the following dependencies:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { useEffect, Fragment } from "react";
import { useFormikContext } from "formik";
import { Formik } from "formik";


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Since we are using Formik DOM, so we are able to use &lt;strong&gt;useFormikContext&lt;/strong&gt;. Because, its easy to read and effective separation of code&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.2.)&lt;/strong&gt; Using a Component for setErrors of Formik library&lt;/p&gt;

&lt;p&gt;This component is responsible for receiving a prop of error messages (&lt;strong&gt;setErrors&lt;/strong&gt;) and setting an errors from our backend request that we want to show on our form or within the fields.&lt;/p&gt;

&lt;p&gt;I used &lt;strong&gt;useEffect&lt;/strong&gt; as watcher of &lt;strong&gt;setErrors&lt;/strong&gt; prop for every time the errors from backend request has changes.&lt;/p&gt;

&lt;p&gt;I used &lt;strong&gt;useFormikContext&lt;/strong&gt; to have access in &lt;strong&gt;setErrors&lt;/strong&gt; from the Formik Provider as Formik component.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

const FormikWithSetErrors = ({ children, setErrors })  =&amp;gt; {

    const { setErrors:setBackendErrors } = useFormikContext();

    useEffect(()=&amp;gt;{
        if(setErrors) setBackendErrors(setErrors);
    },[setErrors]);

    return &amp;lt;Fragment&amp;gt;{children}&amp;lt;/Fragment&amp;gt;;
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;3.3.)&lt;/strong&gt; Get values from Formik provider&lt;/p&gt;

&lt;p&gt;I wrapped the Formik component while our &lt;strong&gt;FormikWithSetErrors&lt;/strong&gt; is our child component. To access the formik provider's value.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

const FormikForm = ({ children, setErrors, ...otherProps }) =&amp;gt; {
    return (
        &amp;lt;Formik {...otherProps}&amp;gt;
            &amp;lt;FormikWithSetErrors setErrors={setErrors}&amp;gt;
                {children}
            &amp;lt;/FormikWithSetErrors&amp;gt;
        &amp;lt;/Formik&amp;gt; 
    );
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Formik/index&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { useEffect, Fragment } from "react";
import { useFormikContext } from "formik";
import { Formik } from "formik";

const FormikWithSetErrors = ({ children, setErrors })  =&amp;gt; {

    const { setErrors:setBackendErrors } = useFormikContext();

    useEffect(()=&amp;gt;{
        if(setErrors) setBackendErrors(setErrors);
    },[setErrors]);

    return &amp;lt;Fragment&amp;gt;{children}&amp;lt;/Fragment&amp;gt;;
}

const FormikForm = ({ children, setErrors, ...otherProps }) =&amp;gt; {
    return (
        &amp;lt;Formik {...otherProps}&amp;gt;
            &amp;lt;FormikWithSetErrors setErrors={setErrors}&amp;gt;
                {children}
            &amp;lt;/FormikWithSetErrors&amp;gt;
        &amp;lt;/Formik&amp;gt; 
    );
}

export default FormikForm;



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;For UI &lt;/p&gt;

&lt;p&gt;I used Material-UI for faster demonstration and easy frontend development&lt;/p&gt;

&lt;p&gt;I made at least two component for sample form fields that we will use to demonstrate the Formik.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ./components
   ../Button/index.js
   ../TextField/index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here's the snippet code of two components:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Button/index.js&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { useFormikContext } from "formik";
import { Button } from "@material-ui/core";

const FormButton = ({ children, otherProps }) =&amp;gt; {
  const { submitForm } = useFormikContext();

  const handleSubmit = () =&amp;gt; {
    // this will trigger the &amp;lt;Formik&amp;gt; prodiver
    submitForm();
  };

  const configFormButton = {
    ...otherProps,
    variant: "contained",
    color: "primary",
    fullWidth: true,
    onClick: handleSubmit
  };

  return &amp;lt;Button {...configFormButton}&amp;gt;{children}&amp;lt;/Button&amp;gt;;
};

export default FormButton;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;TextField/index.js&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { TextField } from "@material-ui/core";
import { useField } from "formik";

const FormTextField = ({ name, ...otherProps }) =&amp;gt; {
  const [field, meta] = useField(name);

  const configFormTextField = {
    ...field,
    ...otherProps,
    variant: "outlined",
    fullWidth: true,
    size: "small"
  };

  if (meta &amp;amp;&amp;amp; meta.error) {
    configFormTextField.error = true;
    configFormTextField.helperText = meta.error;
  }

  return &amp;lt;TextField {...configFormTextField} /&amp;gt;;
};

export default FormTextField;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;I created a validation schema for client validation use. Using a library &lt;strong&gt;Yup&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ./components
     ../validationSchema.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;validationSchema.js&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import * as Yup from "yup";

const ValidationSchema = Yup.object().shape({
  firstName: Yup.string().required("First Name is required")
});

export default ValidationSchema;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;I created a fakeBackend hook request using &lt;strong&gt;setTimeout&lt;/strong&gt;, just to simulate the producing of error response message.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ./components
     ../fakeBackend.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;fakeBackend.js&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { useState } from "react";

const useFakeBackend = () =&amp;gt; {
  const [errors, setErrors] = useState({});

  // simulating a backend request
  const setRequest = () =&amp;gt; {
    setTimeout(() =&amp;gt; {
      setErrors((errors) =&amp;gt; ({
        firstName: "Please enter a valid First Name "
      }));
    }, 2000);
  };

  return { errors, setRequest };
};

export default useFakeBackend;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Finally!!!! Now were almost there!! 😊😊😊&lt;/p&gt;

&lt;p&gt;This is the final setup of our created components for simulation&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App.js&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { Grid } from "@material-ui/core";
import Formik from "./components/Formik/index";
import Button from "./components/Button/index";
import TextField from "./components/TextField/index";
import ValidationSchema from "./components/validationSchema";
import useFakeBackend from "./components/fakeBackend";

export default function App() {
  const { errors, setRequest } = useFakeBackend();

  return (
    &amp;lt;Formik
      initialValues={{ firstName: "" }}
      validationSchema={ValidationSchema}
      enableReinitialize={true}
      setErrors={errors}
      onSubmit={() =&amp;gt; {
        alert("backend requesting...");
        setRequest();
      }}
    &amp;gt;
      &amp;lt;Grid container spacing={2}&amp;gt;
        &amp;lt;Grid item xs={12}&amp;gt;
          &amp;lt;label&amp;gt;First Name&amp;lt;/label&amp;gt;
        &amp;lt;/Grid&amp;gt;
        &amp;lt;Grid item xs={12}&amp;gt;
          &amp;lt;TextField name="firstName" /&amp;gt;
        &amp;lt;/Grid&amp;gt;
        &amp;lt;Grid item xs={12}&amp;gt;
          &amp;lt;Button&amp;gt;Submit&amp;lt;/Button&amp;gt;
        &amp;lt;/Grid&amp;gt;
      &amp;lt;/Grid&amp;gt;
    &amp;lt;/Formik&amp;gt;
  );
}



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, our UI form is now done!!!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4dpoqfmuj86pz6h0ifr9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4dpoqfmuj86pz6h0ifr9.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can fork the whole sample project here:&lt;br&gt;
&lt;a href="https://codesandbox.io/s/formik-context-jsoe0?file=/src/App.js" rel="noopener noreferrer"&gt;https://codesandbox.io/s/formik-context-jsoe0?file=/src/App.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's all thank you guys!!! 😊😊😊&lt;/p&gt;

</description>
      <category>react</category>
      <category>formik</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
