<?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: Satyam Kumar</title>
    <description>The latest articles on DEV Community by Satyam Kumar (@silentvoice143).</description>
    <link>https://dev.to/silentvoice143</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%2F1357649%2F7e4c1d94-46a1-4d65-925f-5f468a61eb94.png</url>
      <title>DEV Community: Satyam Kumar</title>
      <link>https://dev.to/silentvoice143</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/silentvoice143"/>
    <language>en</language>
    <item>
      <title>Zod Validation in [React + Typescript]</title>
      <dc:creator>Satyam Kumar</dc:creator>
      <pubDate>Fri, 31 Jan 2025 20:58:03 +0000</pubDate>
      <link>https://dev.to/silentvoice143/zod-validation-in-react-typescript-28k6</link>
      <guid>https://dev.to/silentvoice143/zod-validation-in-react-typescript-28k6</guid>
      <description>&lt;h2&gt;
  
  
  Zod
&lt;/h2&gt;

&lt;p&gt;Zod is a TypeScript-first schema declaration and validation library. It allows you to define validation schemas for data structures, such as objects, strings, numbers, arrays, etc. Zod validates the data according to the schema and provides clear error messages if the data doesn't match the expected structure.&lt;/p&gt;

&lt;p&gt;Basically it helps us to define a schema for a data structure and then validate that data structure values against the schema and give us proper error.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features of Zod:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Type-safe:&lt;/strong&gt; Zod integrates seamlessly with TypeScript, ensuring that the types of data are validated correctly and that type inference works as expected.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Declarative Validation:&lt;/strong&gt; You define a schema that describes the expected structure of the data, and Zod will automatically validate the data against that schema.&lt;br&gt;
Error Handling: Zod provides detailed, easy-to-understand error messages when validation fails, making it simple to debug validation issues.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Composability:&lt;/strong&gt; You can combine Zod schemas to create more complex data structures, making it easy to reuse and compose validation logic.&lt;br&gt;
Asynchronous Validation: Zod supports asynchronous validation for scenarios such as checking if a value exists in a database.&lt;br&gt;
Okay, Let's move to the coding part, best practice with zod validation library.&lt;br&gt;
For me it is to create a custom hook and then use it everywhere according to my need, you can explore your best choice and let me know more in comments so I can learn new ways too.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now move to the code, so here we are going to create a custom hook named useFormValidation which will return us an object containing three fields &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;errors:&lt;/strong&gt; This will contains an objects with key of form data and error associated with as value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;validateField:&lt;/strong&gt; It is a function which will validate a particular field of a form. It takes two params- first one is name of field which we want to validate and the other one is the value of that field.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;validateForm:&lt;/strong&gt; It is also a function which will validate the whole form in one go. It takes only one param that is form data in the object form.&lt;br&gt;
Okay now its time to create our custom hook as we explained above. First we are going to install zod in our react + typescript project using command&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;



&lt;p&gt;After installing the zod we will create a file name form-validation.tsx and put this code there&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { z, ZodSchema, ZodObject } from "zod";
import { useState, useCallback } from "react";

// Define a generic type for the schema
type SchemaType&amp;lt;T&amp;gt; = ZodObject&amp;lt;{ [K in keyof T]: ZodSchema&amp;lt;T[K]&amp;gt; }&amp;gt;;

/**
 * Custom Hook for form validation using Zod
 */
export const useFormValidation = &amp;lt;T extends Record&amp;lt;string, any&amp;gt;&amp;gt;(
  schema: SchemaType&amp;lt;T&amp;gt;
) =&amp;gt; {
  const [errors, setErrors] = useState&amp;lt;Record&amp;lt;string, string&amp;gt;&amp;gt;({});

  /**
   * Validates a single field based on the schema
   */
  const validateField = useCallback(
    (name: any, value: any) =&amp;gt; {
      try {
        const fieldSchema = schema.shape[name];
        if (!fieldSchema) return;

        const singleFieldSchema = z.object({ [name]: fieldSchema });

        singleFieldSchema.parse({ [name]: value });

        setErrors((prev) =&amp;gt; {
          const newErrors = { ...prev };
          delete newErrors[name as string];
          return newErrors;
        });

        return true;
      } catch (error) {
        if (error instanceof z.ZodError) {
          const fieldError = error.errors[0]?.message;
          setErrors((prev) =&amp;gt; ({
            ...prev,
            [name as string]: fieldError,
          }));
          return false;
        }
      }
    },
    [schema]
  );

  /**
   * Validates the entire form based on the schema
   */
  const validateForm = useCallback(
    (data: T) =&amp;gt; {
      try {
        schema.parse(data);
        setErrors({});
        return { success: true, errors: null };
      } catch (error) {
        if (error instanceof z.ZodError) {
          const newErrors = Object.fromEntries(
            error.errors.map(({ path, message }) =&amp;gt; [path[0], message])
          );
          setErrors(newErrors);
          return { success: false, errors: newErrors };
        }
        return { success: false, errors: { form: "Validation failed" } };
      }
    },
    [schema]
  );

  return {
    errors,
    validateField,
    validateForm,
  };
};


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

&lt;/div&gt;



&lt;p&gt;Let's explain each part &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Explanation&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;1. Type Definition (UseZodValidationProps)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type SchemaType&amp;lt;T&amp;gt; = ZodObject&amp;lt;{ [K in keyof T]: ZodSchema&amp;lt;T[K]&amp;gt; }&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This type defines the shape of the props that the useZodValidation hook will receive. The hook expects a schema prop, which is a ZodSchema (a validation schema from the Zod library). The T represents a generic type for form data (the schema type).&lt;br&gt;
&lt;strong&gt;2. State for Errors (useState)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [errors, setErrors] = useState&amp;lt;Record&amp;lt;string, string&amp;gt;&amp;gt;({});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;errors is a state variable that will store validation errors for each field. It's an object where each key is a field name, and the value is the corresponding error message.&lt;br&gt;
setErrors is used to update this state.&lt;br&gt;
&lt;strong&gt;3. validateField Function&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const validateField = useCallback(
    (name: any, value: any) =&amp;gt; {
      try {
        const fieldSchema = schema.shape[name];
        if (!fieldSchema) return;

        const singleFieldSchema = z.object({ [name]: fieldSchema });

        singleFieldSchema.parse({ [name]: value });

        setErrors((prev) =&amp;gt; {
          const newErrors = { ...prev };
          delete newErrors[name as string];
          return newErrors;
        });

        return true;
      } catch (error) {
        if (error instanceof z.ZodError) {
          const fieldError = error.errors[0]?.message;
          setErrors((prev) =&amp;gt; ({
            ...prev,
            [name as string]: fieldError,
          }));
          return false;
        }
      }
    },
    [schema]
  );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;validateField is called when you want to validate a single field dynamically (e.g., on each input change).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Parameters:&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;**name: **The name of the field to validate (e.g., "email").
value: The current value of the field (e.g., the input value).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;Inside the function:&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;singleFieldSchema.parse({ [name]: value });&lt;/strong&gt; This uses Zod's parse method to validate the specific field (name) against the schema. The schema is designed to validate the entire object, so we pass a partial object with just the field we're validating.
If validation fails we extract the error message from the catch block and update the errors state with the field's error message.
If the field is valid, we remove any previous error for that field from the errors state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. validateForm Function&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const validateForm = useCallback(
    (data: T) =&amp;gt; {
      try {
        schema.parse(data);
        setErrors({});
        return { success: true, errors: null };
      } catch (error) {
        if (error instanceof z.ZodError) {
          const newErrors = Object.fromEntries(
            error.errors.map(({ path, message }) =&amp;gt; [path[0], message])
          );
          setErrors(newErrors);
          return { success: false, errors: newErrors };
        }
        return { success: false, errors: { form: "Validation failed" } };
      }
    },
    [schema]
  );

  return {
    errors,
    validateField,
    validateForm,
  };
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;validateForm is used to validate the entire form (all fields) at once.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Parameters:&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;data:&lt;/strong&gt; The form data (an object) that needs to be validated against the schema.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;Inside the function:&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;parse(data):&lt;/strong&gt; This validates the entire form data.
If validation fails, it formats the error and creates an errors object containing error messages for each invalid field. The setErrors function is then called to update the state with these errors.
If validation passes, it clears any previous errors by setting setErrors({}) and returns true to indicate success.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. Return Object&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return { errors, validateField, validateForm };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The hook returns the following:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;errors:&lt;/strong&gt; The current errors object containing validation error messages for the form fields.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;validateField:&lt;/strong&gt; A function to validate a single field in real-time (for example, when the user types in a field).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;validateForm:&lt;/strong&gt; A function to validate the entire form (for example, when submitting the form).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How This Works in a Component
&lt;/h2&gt;

&lt;p&gt;You can use this hook in your form components to manage field validation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;validateField is used for validating individual fields in real-time (e.g., when a user types in a field).&lt;/li&gt;
&lt;li&gt;validateForm is used when submitting the form, to ensure that all fields are validated at once.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's see an example to use this hook in a form&lt;/p&gt;

&lt;h2&gt;
  
  
  Example Usage in a Component
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from "react";

import { z } from "zod";
import { useFormValidation } from "./hooks/form-validation";

// Define a validation schema using Zod
const schema = z.object({
  name: z.string().min(3, "Name must be at least 3 characters"),
  email: z.string().email("Invalid email address"),
  age: z.preprocess(
    (val) =&amp;gt; Number(val),
    z.number().min(18, "Must be at least 18")
  ),
});

const MyForm = () =&amp;gt; {
  const { errors, validateField, validateForm } = useFormValidation(schema);

  const [formData, setFormData] = useState({
    name: "",
    email: "",
    age: 18,
  });

  const onChangeHandler = (field: keyof typeof formData, value: any) =&amp;gt; {
    setFormData((prev) =&amp;gt; ({ ...prev, [field]: value }));
    validateField(field, value); // Real-time field validation
  };

  const onSubmit = (e: React.FormEvent) =&amp;gt; {
    e.preventDefault();
    // Validate the entire form using formData
    const res = validateForm(formData);
    console.log(res);
    if (res.success) {
      console.log("Form Data:", formData);
    }
  };

  return (
    &amp;lt;form onSubmit={onSubmit} className="space-y-4 p-4 border rounded-md w-80"&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;label&amp;gt;Name:&amp;lt;/label&amp;gt;
        &amp;lt;input
          value={formData.name}
          onChange={(e) =&amp;gt; onChangeHandler("name", e.target.value)}
          className="border p-1 rounded w-full"
        /&amp;gt;
        {errors.name &amp;amp;&amp;amp; &amp;lt;p className="text-red-500"&amp;gt;{errors.name}&amp;lt;/p&amp;gt;}
      &amp;lt;/div&amp;gt;

      &amp;lt;div&amp;gt;
        &amp;lt;label&amp;gt;Email:&amp;lt;/label&amp;gt;
        &amp;lt;input
          value={formData.email}
          onChange={(e) =&amp;gt; onChangeHandler("email", e.target.value)}
          className="border p-1 rounded w-full"
        /&amp;gt;
        {errors.email &amp;amp;&amp;amp; &amp;lt;p className="text-red-500"&amp;gt;{errors.email}&amp;lt;/p&amp;gt;}
      &amp;lt;/div&amp;gt;

      &amp;lt;div&amp;gt;
        &amp;lt;label&amp;gt;Age:&amp;lt;/label&amp;gt;
        &amp;lt;input
          type="number"
          value={formData.age}
          onChange={(e) =&amp;gt; onChangeHandler("age", e.target.value)}
          className="border p-1 rounded w-full"
        /&amp;gt;
        {errors.age &amp;amp;&amp;amp; &amp;lt;p className="text-red-500"&amp;gt;{errors.age}&amp;lt;/p&amp;gt;}
      &amp;lt;/div&amp;gt;

      &amp;lt;button
        type="submit"
        className="bg-blue-500 text-white px-4 py-2 rounded"
      &amp;gt;
        Submit
      &amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
  );
};

export default MyForm;

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

&lt;/div&gt;



</description>
      <category>zod</category>
      <category>validation</category>
      <category>typescript</category>
      <category>react</category>
    </item>
    <item>
      <title>useState and useEffect</title>
      <dc:creator>Satyam Kumar</dc:creator>
      <pubDate>Sun, 19 Jan 2025 18:34:28 +0000</pubDate>
      <link>https://dev.to/silentvoice143/usestate-and-useeffect-5f16</link>
      <guid>https://dev.to/silentvoice143/usestate-and-useeffect-5f16</guid>
      <description>&lt;p&gt;We’re diving into two of the most essential React hooks: useState and useEffect. Whether you’re a beginner or preparing for job interviews.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;1. What are React Hooks?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;React Hooks are special functions that let you use React features like state and lifecycle methods in functional components. Before hooks, we relied on class components, but hooks have simplified development and made code more readable.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;2. useState&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The useState hook is used to add state to functional components. It returns two things: the current state and a function to update that state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Count: {count}&amp;lt;/h1&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setCount(count + 1)}&amp;gt;Increment&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default Counter;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in this example we are simply setting the count with the help of useState on click event. When we will click the button it will increase the count with 1.&lt;/p&gt;

&lt;p&gt;Common Mistakes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;"&lt;strong&gt;Updating state directly:&lt;/strong&gt; count++ — this won't work! Always use the setState function."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"&lt;strong&gt;Using useState outside a functional component&lt;/strong&gt;. Hooks must be called within the component body."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Inside Another Function or Conditional Block (Not Allowed)&lt;/strong&gt;&lt;br&gt;
React hooks must be called in the same order on every render. If you try to call useState conditionally or inside a nested function, React can't guarantee this, leading to errors.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example: Incorrect Usage&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function Counter() {
  if (true) { // This is a conditional block
    const [count, setCount] = useState(0); // ❌ This will throw an error
  }

  return &amp;lt;div&amp;gt;Invalid Usage&amp;lt;/div&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Error Message:&lt;br&gt;
&lt;strong&gt;"React Hook 'useState' is called conditionally. React Hooks must be called in the exact same order in every component render."&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;3. useEffect&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;useEffect is a React hook that handles side effects in functional components, like data fetching, subscriptions, or manually updating the DOM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Syntax:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; {
  // Your side effect code here
  return () =&amp;gt; {
    // Cleanup code here (optional)
  };
}, [dependencies]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The dependencies array controls when the effect runs:&lt;/strong&gt;&lt;br&gt;
Empty ([]): Runs only once, when the component mounts.&lt;br&gt;
No array: Runs after every render.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Specified dependencies:&lt;/strong&gt; Runs only when those values change.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example: Timer with useEffect&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState, useEffect } from 'react';

function Timer() {
  const [seconds, setSeconds] = useState(0);

  useEffect(() =&amp;gt; {
    const interval = setInterval(() =&amp;gt; {
      setSeconds((prev) =&amp;gt; prev + 1);
    }, 1000);

    return () =&amp;gt; clearInterval(interval); // Cleanup the interval on unmount
  }, []); // Empty array ensures this runs only once

  return &amp;lt;h1&amp;gt;Seconds: {seconds}&amp;lt;/h1&amp;gt;;
}

export default Timer;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How it works:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The useEffect runs after the component mounts, setting up an 
interval to update seconds.&lt;/li&gt;
&lt;li&gt;The cleanup function clears the interval when the component 
unmounts, preventing memory leaks.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Common Mistakes with useEffect&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Missing Dependencies:&lt;/strong&gt;
If you forget to include variables in the dependency array, the effect might not behave as expected.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; {
  console.log(data); // `data` should be in the dependency array
}, [data]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Infinite Loops:&lt;/strong&gt;
Updating state inside an effect without proper dependencies can cause the effect to run infinitely:
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;



&lt;p&gt;useEffect(() =&amp;gt; {&lt;br&gt;
  setCount(count + 1); // This causes an infinite loop&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advanced Use Cases&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Updating Objects in useState&lt;/strong&gt;
When working with objects, always copy the previous state using the spread operator to avoid overwriting unintended properties.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [user, setUser] = useState({ name: '', age: 0 });

function updateName() {
  setUser((prevUser) =&amp;gt; ({ ...prevUser, name: 'John' }));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Conditional Effects&lt;/strong&gt;
Only run an effect if a condition is met.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; {
  if (someCondition) {
    console.log('Condition met!');
  }
}, [someCondition]); // Runs when `someCondition` changes 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fetching Data&lt;/strong&gt;
A common use of useEffect is fetching data from an API.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; {
  async function fetchData() {
    const response = await fetch('https://api.example.com/data');
    const result = await response.json();
    console.log(result);
  }
  fetchData();
}, []); // Runs only once
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Job Interview Questions&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;What are hooks? Can they be used in class components?&lt;br&gt;
Hooks are functions that let you use React features in functional &lt;br&gt;
components. They cannot be used in class components.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What happens if you don’t provide a dependency array in useEffect?&lt;br&gt;
The effect runs after every render, potentially leading to &lt;br&gt;
performance issues or infinite loops.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How do you clean up effects?&lt;br&gt;
By returning a cleanup function from useEffect:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; {
  const interval = setInterval(() =&amp;gt; console.log('Running'), 1000);
  return () =&amp;gt; clearInterval(interval); // Cleanup
}, []);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Why do we use functional updates in useState?
To ensure the state is updated based on the most recent value when 
the updates depend on the previous state:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;setState((prevState) =&amp;gt; prevState + 1);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;There is a question related to this concept asked commonly in interviews.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  const incrementCount = () =&amp;gt; {
    setCount(count + 1); // Updates count by +1
    setCount(count + 1); // Still uses the same count value (not updated yet)
    setCount(count + 1); // Again, uses the same count value
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Count: {count}&amp;lt;/h1&amp;gt;
      &amp;lt;button onClick={incrementCount}&amp;gt;Increment&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default Counter;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's say if we run this code what you expect to happen. The thing is here you will think if my current count is 1 then it will be 4 after clicking the button but in reality it gonna update the count by just 1 that is count will become 2.&lt;/p&gt;

&lt;p&gt;Let's understand this, everytime we do &lt;code&gt;setState(count+1)&lt;/code&gt;. It is using the same count not the currently updated count because the count will update only at the time of rerendering. When you update a state in React like &lt;code&gt;setState(count + 1)&lt;/code&gt; multiple times in a row, the updates do not immediately reflect in the current render. Instead, React batches state updates for performance, and each setState call uses the current value of the state at the time of its execution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;solution:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  const incrementCount = () =&amp;gt; {
    setCount((prevCount) =&amp;gt; prevCount + 1); // Uses the latest value of count
    setCount((prevCount) =&amp;gt; prevCount + 1); // Updates based on the new value
    setCount((prevCount) =&amp;gt; prevCount + 1); // Updates again based on the latest value
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Count: {count}&amp;lt;/h1&amp;gt;
      &amp;lt;button onClick={incrementCount}&amp;gt;Increment&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default Counter;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;When using the functional form of setState, React ensures that each update is based on the most recent state, even if multiple updates are queued.&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What Happens Without Clearing the Interval?&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Interval Keeps Running:&lt;/strong&gt;&lt;br&gt;
When you set an interval using setInterval, the JavaScript runtime keeps executing the callback function at the specified time interval, regardless of whether the component is still in the DOM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Access to Unmounted Component:&lt;/strong&gt;&lt;br&gt;
The interval callback may try to update the state or interact with the DOM of the component that has already been unmounted. Since the component no longer exists, this leads to warnings or errors.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example warning in React:&lt;br&gt;
&lt;code&gt;Can't perform a React state update on an unmounted component.&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Memory Leak:&lt;/strong&gt;
Since the interval is still running and holding a reference to the callback function, memory associated with the component (e.g., variables, state) cannot be garbage collected. This increases memory usage over time and can degrade application performance.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>usestate</category>
      <category>useeffect</category>
      <category>reactnative</category>
      <category>react</category>
    </item>
    <item>
      <title>Build a Secretkeeper app and generate QR code for your message</title>
      <dc:creator>Satyam Kumar</dc:creator>
      <pubDate>Sat, 16 Mar 2024 15:20:16 +0000</pubDate>
      <link>https://dev.to/silentvoice143/build-a-secretkeeper-app-and-generate-qr-code-for-your-message-4jch</link>
      <guid>https://dev.to/silentvoice143/build-a-secretkeeper-app-and-generate-qr-code-for-your-message-4jch</guid>
      <description>&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Secretkeeper app let you generate a QR code for your text message which you can share and download and when you scan that QR code with scanner you will get the text message.It is a React+Vite+Typescript app which uses react-qr-code package for generating QR code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites#&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic knowledge of React.js&lt;/li&gt;
&lt;li&gt;Basic Typescript
&lt;/li&gt;
&lt;li&gt;Tailwind css &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;To create vite application with react template follow these commands:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Terminal&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$npx create-vite secretkeeper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that choose React template and then choose typescript and press enter.&lt;/p&gt;

&lt;p&gt;Now move to secretkeeper directory in terminal or open that folder in terminal directly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Terminal&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$cd secretkeeper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Setup tailwind css in our project#&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To setup tailwind css the best way is ofcourse go through tailwind css docs &lt;a href="https://tailwindcss.com/docs/guides/vite"&gt;https://tailwindcss.com/docs/guides/vite&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure to add content in tailwind.config.js &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;tailwind.config.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/** @type {import('tailwindcss').Config} */
export default {
  content: ["./src/**/*.{html,js,ts,jsx,tsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, install all of the dependencies needed to build this app:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Terminal&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @iconify/react html-to-image react-qr-code 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Documentation related to these packages:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;@iconify/react &lt;a href="https://www.npmjs.com/package/@iconify/react"&gt;https://www.npmjs.com/package/@iconify/react&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;html-to-image &lt;a href="https://www.npmjs.com/package/html-to-image?activeTab=readme"&gt;https://www.npmjs.com/package/html-to-image?activeTab=readme&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;react-qr-code &lt;a href="https://www.npmjs.com/package/react-qr-code?activeTab=readme"&gt;https://www.npmjs.com/package/react-qr-code?activeTab=readme&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Delete everything from App.tsx in src directory and code it as:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App.tsx&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import QRCodeGenerator from "./Qrcode";

import "./index.css";

const App: React.FC = () =&amp;gt; {
  return (
    &amp;lt;div className="flex items-center justify-center w-screen h-screen bg-red-200 App"&amp;gt;
      &amp;lt;div className="w-[400px] max-[700px]:w-full max-[700px]:h-full py-8  bg-[#FFBBBB]
     flex flex-col items-center relative"&amp;gt;
        &amp;lt;h1 className="text-xl"&amp;gt;SecretKeeper&amp;lt;/h1&amp;gt;
        &amp;lt;QRCodeGenerator /&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In App.tsx we import Qrcode component as QRCodeGenerator.&lt;/p&gt;

&lt;p&gt;Now we create Qrcode.jsx component in src directory.This component will include an input box for entering text messages and a button to generate a QR code. Additionally, it will provide options todownload the QR code as a PNG file or share it using the Web Share API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qrcode.tsx&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useRef, useState } from "react";
import QRCode from "react-qr-code";
import { Icon } from "@iconify/react";
import * as htmlToImage from "html-to-image";

const QRCodeGenerator: React.FC = () =&amp;gt; {
  const [inputValue, setInputValue] = useState&amp;lt;string&amp;gt;("");
  const [qrData, setQRData] = useState("");
  const [IsQrcode, setIsQrcode] = useState&amp;lt;boolean&amp;gt;(false);

  const handleInputChange = (e: React.ChangeEvent&amp;lt;HTMLInputElement&amp;gt;) =&amp;gt; {
    setInputValue(e.target.value);
  };

  const qrRef = useRef(null);

  const generateQRCode = () =&amp;gt; {
    // Generate your QR code data here, for example:
    setIsQrcode(true);
    setQRData(inputValue);
  };

  const downloadQRCode = async () =&amp;gt; {
    if (!qrRef.current) return;

    const dataUrl = await htmlToImage.toPng(qrRef.current, {
      quality: 1,
      // width: qrRef.current.offsetWidth * 2,
      // height: qrRef.current.offsetHeight * 2,
    });

    // download image
    const link = document.createElement("a");
    link.download = "html-to-img.png";
    link.href = dataUrl;
    link.click();
  };

  const shareQRCode = () =&amp;gt; {
    if (!qrRef.current) return;
    // Fallback for sharing via WhatsApp

    htmlToImage.toBlob(qrRef.current).then(function (blob) {
      if (!blob) return;
      const filesArray = [
        new File([blob], "qrcode.png", { type: "image/png" }),
      ];
      if (navigator.share) {
        navigator
          .share({
            files: filesArray,
            title: "QR Code",
            text: "Scan this QR code",
          })
          .then(() =&amp;gt; console.log("Shared successfully"))
          .catch((error) =&amp;gt; console.error("Error sharing:", error));
      } else {
        // console.log("Web Share API not supported");
        const blobUrl = URL.createObjectURL(blob); // Convert Blob to a data URL
        const whatsappURL = `whatsapp://send?text=Scan this QR code&amp;amp;files=${encodeURIComponent(
          blobUrl
        )}`;

        // Fallback for sharing via email
        const emailBody = "Scan this QR code";
        const emailSubject = "QR Code";
        const emailURL = `mailto:?subject=${encodeURIComponent(
          emailSubject
        )}&amp;amp;body=${encodeURIComponent(emailBody)}`;
        // Open a new window to trigger the default email client
        window.open(emailURL);
        // Open WhatsApp if the device supports it
        window.location.href = whatsappURL;
      }
    });
  };

  return (
    &amp;lt;div className="relative flex flex-col items-center justify-center flex-1 w-full p-4"&amp;gt;
      &amp;lt;input
        className="w-full p-4 border-none outline-none"
        type="text"
        value={inputValue}
        onChange={handleInputChange}
        placeholder="Enter text for QR code"
      /&amp;gt;
      &amp;lt;button
        className="px-4 py-2 my-4 bg-white border-none outline-none"
        onClick={generateQRCode}
      &amp;gt;
        Generate QRCode
      &amp;lt;/button&amp;gt;
      {IsQrcode &amp;amp;&amp;amp; (
        &amp;lt;div className="flex justify-between w-full my-4 "&amp;gt;
          &amp;lt;div className="qrcode"&amp;gt;
            &amp;lt;QRCode
              style={{
                background: "white",

                border: "2px solid black", // Set border style
                padding: "10px", // Add some padding for better appearance
                display: "inline-block", // Ensure the container wraps QR code
              }}
              ref={qrRef}
              className="w-[150px] h-[150px] rounded-md"
              value={qrData}
            /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div className="flex items-center justify-center buttons"&amp;gt;
            &amp;lt;button
              className="p-2 mx-4 bg-white rounded-full download"
              onClick={downloadQRCode}
            &amp;gt;
              &amp;lt;Icon
                className="w-10 h-10"
                icon="material-symbols:download-sharp"
              /&amp;gt;
            &amp;lt;/button&amp;gt;
            &amp;lt;button
              className="p-2 mx-4 bg-white rounded-full send"
              onClick={shareQRCode}
            &amp;gt;
              &amp;lt;Icon className="w-10 h-10" icon="bitcoin-icons:share-filled" /&amp;gt;
            &amp;lt;/button&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      )}
    &amp;lt;/div&amp;gt;
  );
};

export default QRCodeGenerator;

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

&lt;/div&gt;



&lt;p&gt;In this file we have used React useRef Hook to refer qrcode html element.qrRef is refering to QRCode html element so that we can download it using html-to-tmage package and share it.&lt;/p&gt;

&lt;p&gt;Here we imported QRCode from react-qr-code package.To generate QRCode using this package we just need to pass a prop value={qrData}, qrData is the message we want to encode  as QRCode.&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
Then we created a function handleInputChange for contorolled input box and other function generateQRCode, generate QRCode button will call this function onclick and this will set isqrcode=true so that qrcode will be visible on the page and also setQRData(inputValue) using Reacthook. Then we will use qrData to generate QRCode.&lt;/p&gt;

&lt;p&gt;Basically there is two more function one for downloading QRCode as png and other for sharing using Web Share API.&lt;/p&gt;

&lt;p&gt;d&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ownloadQRCode( )&lt;/strong&gt;: This function invoked when user click on download button and then uses html-to-image package to generate png of QRCode and it will be automatically downloaded using anchor tag.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;shareQRCode( )&lt;/strong&gt;: In the context of the htmlToImage.toBlob() function, it converts the content of an HTML element (in this case, the QR code container) into an image Blob. This Blob can then be used for various purposes, such as downloading the image or sharing it via the Web Share API.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope you like this post, don't forget to follow me for more&lt;br&gt;
exciting post like this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Git Repo:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/silentvoice143/secretkeeper"&gt;https://github.com/silentvoice143/secretkeeper&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;........Thanks........&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
