<?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: Khalid Kakar</title>
    <description>The latest articles on DEV Community by Khalid Kakar (@khalidkhankakar).</description>
    <link>https://dev.to/khalidkhankakar</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%2F1450593%2Ff2bb0420-de5b-4ef7-a66d-660226c5adcf.jpg</url>
      <title>DEV Community: Khalid Kakar</title>
      <link>https://dev.to/khalidkhankakar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/khalidkhankakar"/>
    <language>en</language>
    <item>
      <title>Learn server actions in Nextjs</title>
      <dc:creator>Khalid Kakar</dc:creator>
      <pubDate>Thu, 13 Feb 2025 08:03:23 +0000</pubDate>
      <link>https://dev.to/khalidkhankakar/learn-this-the-server-actions-in-nextjs-237h</link>
      <guid>https://dev.to/khalidkhankakar/learn-this-the-server-actions-in-nextjs-237h</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/khalidkhankakar" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1450593%2Ff2bb0420-de5b-4ef7-a66d-660226c5adcf.jpg" alt="khalidkhankakar"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/khalidkhankakar/nextjs-server-actions-3oc9" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;NextJs Server Actions&lt;/h2&gt;
      &lt;h3&gt;Khalid Kakar ・ Feb 13&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#nextjs&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#react&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>nextjs</category>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>NextJs Server Actions</title>
      <dc:creator>Khalid Kakar</dc:creator>
      <pubDate>Thu, 13 Feb 2025 08:02:13 +0000</pubDate>
      <link>https://dev.to/khalidkhankakar/nextjs-server-actions-3oc9</link>
      <guid>https://dev.to/khalidkhankakar/nextjs-server-actions-3oc9</guid>
      <description>&lt;p&gt;In this article, we will explore Next.js Server Actions, which were introduced in Next.js 14 and are now stable. This is a good opportunity to learn and use them in large Next.js projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are server actions? 😊
&lt;/h2&gt;

&lt;p&gt;Actions can only be run on the server. They are simple, regular, and asynchronous functions that are helpful for async tasks like file management, database requests (CRUD operations), and more.&lt;/p&gt;

&lt;p&gt;In simple terms, Server Actions are equivalent to API calls, but they are fully integrated. This is because we can send headers and cookies directly in Server Actions. 👍&lt;/p&gt;

&lt;h2&gt;
  
  
  Purpose of Server Action
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The purpose of Server Actions is to make data fetching and mutations simpler while removing unnecessary APIs.&lt;/li&gt;
&lt;li&gt;They are simpler than API calls and require less boilerplate code.&lt;/li&gt;
&lt;li&gt;Server Actions can be directly called from both types of components: Server Components and Client Components.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Behaviour of Server Action
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Server Action arguments and return values must be serializable by React. Serializable means they can be converted into a format that can be stored or transmitted, such as primitive data types in JavaScript. Non-serializable values include functions, class instances, symbols, DOM elements, and BigInt.&lt;/li&gt;
&lt;li&gt;Server Actions inherit the runtime of the page and layout. If the page and layout use the Edge runtime, the Server Action must run in the Edge runtime, and vice versa for the Node.js runtime.&lt;/li&gt;
&lt;li&gt;Server Actions can also handle caching and revalidate data. 🤞&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to implement?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;'use server';&lt;/code&gt; directive is used to create a Server Action.&lt;br&gt;
For 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 { createTask } from "../_actions/actions";

export default function TodoForm() {

    return (
        &amp;lt;form action={async (formData) =&amp;gt; {
            'use server';
            // trigrred server action which will run only on server
            await createTask(formData)
        }}&amp;gt;

            {/* form body */}

        &amp;lt;/form&amp;gt;
    )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example, we created a form and passed an asynchronous function to the form’s action attribute. Inside that function, we used the use server directive, which ensures that the function runs only on the server.&lt;/p&gt;

&lt;p&gt;That was a simple example of a Server Action. However, the most convenient approach is to create a separate file for the Server Action. In that file, write &lt;code&gt;'use server';&lt;/code&gt; at the top to ensure the function executes only on the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can we conveniently implement Server Actions in a real-world application?
&lt;/h2&gt;

&lt;p&gt;In this example, we will create a to-do application with a file system, using Server Actions in Next.js 14.&lt;br&gt;
&lt;strong&gt;Step 1&lt;/strong&gt;&lt;br&gt;
Initialize you latest Nextjs project.&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-next-app@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;&lt;br&gt;
Create form for the task creation&lt;br&gt;
components/task-form.tsx&lt;br&gt;
&lt;/p&gt;

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

import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { useState } from "react"


export default function TodoForm() {
    const [title, setTitle] = useState("")
    const [desc, setDesc] = useState("")
    const [type, setType] = useState&amp;lt;'TODO'|'IN_PROGRESS'|'COMPLETED'&amp;gt;('TODO')


   async function onSubmit(formData: FormData) {

        formData.append('type', type)

    }

    return (
        &amp;lt;div className="w-2/3 md:w-1/3   mx-auto p-4 space-y-6"&amp;gt;
            &amp;lt;div className="space-y-2 text-center"&amp;gt;
                &amp;lt;h1 className="text-3xl font-bold"&amp;gt;Create Todo&amp;lt;/h1&amp;gt;
                &amp;lt;p className="text-gray-500 dark:text-gray-400"&amp;gt;Add a new todo item to your list&amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
            {/*  */}
            &amp;lt;form action={onSubmit} className="space-y-4 w-full"&amp;gt;
                &amp;lt;Input placeholder="Enter todo title" name="title" onChange={(e) =&amp;gt; setTitle(e.target.value)} value={title} /&amp;gt;
                &amp;lt;Textarea placeholder="Enter todo description" className="min-h-[100px]" name="desc" onChange={(e) =&amp;gt; setDesc(e.target.value)} value={desc} /&amp;gt;
                &amp;lt;Select onValueChange={(e) =&amp;gt; setType(e as 'TODO'|'IN_PROGRESS'|'COMPLETED')} defaultValue={type}&amp;gt;
                    &amp;lt;SelectTrigger&amp;gt;
                        &amp;lt;SelectValue placeholder="Select a status" /&amp;gt;
                    &amp;lt;/SelectTrigger&amp;gt;
                    &amp;lt;SelectContent&amp;gt;
                        &amp;lt;SelectItem value="TODO"&amp;gt;Todo&amp;lt;/SelectItem&amp;gt;
                        &amp;lt;SelectItem value="IN_PROGRESS"&amp;gt;In Progress&amp;lt;/SelectItem&amp;gt;
                        &amp;lt;SelectItem value="COMPLETED"&amp;gt;Completed&amp;lt;/SelectItem&amp;gt;
                    &amp;lt;/SelectContent&amp;gt;
                &amp;lt;/Select&amp;gt;

                &amp;lt;Button type="submit" className="w-full"&amp;gt;
                    Create Todo
                &amp;lt;/Button&amp;gt;
            &amp;lt;/form&amp;gt;
        &amp;lt;/div&amp;gt;
    )
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;&lt;br&gt;
Make the directory inside that directory create file for task action like &lt;code&gt;actions/task-actions.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'use server';
import fs from 'fs';
import { revalidatePath } from 'next/cache';


const FILE_PATH = './app/server-action/_actions/task.json'

export const createTask = async (formData: FormData): Promise&amp;lt;{ success: boolean }&amp;gt; =&amp;gt; {
    try {
        const title = formData.get('title') as string
        const desc = formData.get('desc') as string
        const type = formData.get('type') as 'TODO' | 'IN_PROGRESS' | 'COMPLETED'

        // Ensure the file exists before reading
        if (!fs.existsSync(FILE_PATH)) {
            fs.writeFileSync(FILE_PATH, JSON.stringify({ tasks: [] }))
        }

        const allTask = fs.readFileSync(FILE_PATH, 'utf-8')
        const task = JSON.parse(allTask)

        console.log({task})

        const newId = task.tasks.length ? task.tasks.length + 1 : 0
        task.tasks.push({ id: newId, title, desc, type })

        fs.writeFileSync(FILE_PATH, JSON.stringify(task))
        revalidatePath('/server-action')
        return { success: true }
    } catch (error) {
        console.error('Error creating task:', error)
        return { success: false }
    }
}


export const getAllTasks = async(): Promise&amp;lt;{ tasks: { id: number; title: string; desc: string; type: 'TODO' | 'IN_PROGRESS' | 'COMPLETED' }[]}&amp;gt; =&amp;gt; {
    const allTask = fs.readFileSync(FILE_PATH, 'utf-8')
    return JSON.parse(allTask)
}

export const deleteTaskById = async (id: number): Promise&amp;lt;{ success: boolean }&amp;gt; =&amp;gt; {
    try {

        const allTask = fs.readFileSync(FILE_PATH, 'utf-8');
        const task = JSON.parse(allTask);

        const updatedTasks = task.tasks.filter((task: { id: number; }) =&amp;gt; task.id !== id);  

        fs.writeFileSync(FILE_PATH, JSON.stringify({ tasks: updatedTasks }));

        revalidatePath('/server-action')

        return { success: true };
    } catch (error) {
        console.error('Error deleting task:', error);
        return { success: false };
    }
}

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

&lt;/div&gt;



&lt;p&gt;We will use a JSON file to manipulate tasks by applying different CRUD operations, following the same procedure used for databases. This is just for simplicity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt;&lt;br&gt;
Trigger the server action inside &lt;code&gt;components/task-form.tsx&lt;/code&gt; file to create the new task in JSON file.&lt;br&gt;
&lt;/p&gt;

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

import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { useState } from "react"
import { createTask } from "../_actions/actions"
import { useToast } from "@/hooks/use-toast"


export default function TodoForm() {
    const [title, setTitle] = useState("")
    const [desc, setDesc] = useState("")
    const [type, setType] = useState&amp;lt;'TODO' | 'IN_PROGRESS' | 'COMPLETED'&amp;gt;('TODO')
    const { toast } = useToast()

    async function onSubmit(formData: FormData) {

        formData.append('type', type)
        const res = await createTask(formData)
        if (res.success) {
            setTitle("")
            setDesc("")
            setType('TODO')
            toast({
                title: "Success",
                description: "Task created successfully",
            })
        }
        else {
            toast({
                title: "Error",
                description: "Something went wrong",
                variant: 'destructive'
            })
        }
    }

    return (
        &amp;lt;div className="w-2/3 md:w-1/3   mx-auto p-4 space-y-6"&amp;gt;
            &amp;lt;div className="space-y-2 text-center"&amp;gt;
                &amp;lt;h1 className="text-3xl font-bold"&amp;gt;Create Todo&amp;lt;/h1&amp;gt;
                &amp;lt;p className="text-gray-500 dark:text-gray-400"&amp;gt;Add a new todo item to your list&amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
            {/*  */}
            &amp;lt;form action={onSubmit} className="space-y-4 w-full"&amp;gt;
                &amp;lt;Input placeholder="Enter todo title" name="title" onChange={(e) =&amp;gt; setTitle(e.target.value)} value={title} /&amp;gt;
                &amp;lt;Textarea placeholder="Enter todo description" className="min-h-[100px]" name="desc" onChange={(e) =&amp;gt; setDesc(e.target.value)} value={desc} /&amp;gt;
                &amp;lt;Select onValueChange={(e) =&amp;gt; setType(e as 'TODO' | 'IN_PROGRESS' | 'COMPLETED')} defaultValue={type}&amp;gt;
                    &amp;lt;SelectTrigger&amp;gt;
                        &amp;lt;SelectValue placeholder="Select a status" /&amp;gt;
                    &amp;lt;/SelectTrigger&amp;gt;
                    &amp;lt;SelectContent&amp;gt;
                        &amp;lt;SelectItem value="TODO"&amp;gt;Todo&amp;lt;/SelectItem&amp;gt;
                        &amp;lt;SelectItem value="IN_PROGRESS"&amp;gt;In Progress&amp;lt;/SelectItem&amp;gt;
                        &amp;lt;SelectItem value="COMPLETED"&amp;gt;Completed&amp;lt;/SelectItem&amp;gt;
                    &amp;lt;/SelectContent&amp;gt;
                &amp;lt;/Select&amp;gt;

                &amp;lt;Button type="submit" className="w-full"&amp;gt;
                    Create Todo
                &amp;lt;/Button&amp;gt;
            &amp;lt;/form&amp;gt;
        &amp;lt;/div&amp;gt;
    )
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 5&lt;/strong&gt;&lt;br&gt;
Get all tasks in the &lt;code&gt;'page.tsx'&lt;/code&gt; file and also create a task card inside the components directory, like &lt;code&gt;'components/task-card.tsx'&lt;/code&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 TodoForm from './_components/todo-form'
import { getAllTasks } from './_actions/actions'
import TaskCard from './_components/task-card'

const page = async () =&amp;gt; {
  const {tasks} =await getAllTasks()

  return (
    &amp;lt;div className='min-h-screen flex py-10 items-center justify-center flex-col gap-y-3'&amp;gt;
      &amp;lt;div className='flex items-center flex-wrap gap-4 justify-center'&amp;gt;
      {
        tasks.map((task) =&amp;gt; (
          &amp;lt;TaskCard  key={task.id} title={task.title} description={task.desc} id={task.id} type={task.type} /&amp;gt;
        ))
      }
      &amp;lt;/div&amp;gt;
      &amp;lt;TodoForm /&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;task-card.tsx&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'use client'
import { Pencil, Trash2 } from "lucide-react"
import { deleteTaskById } from "../_actions/actions"
import { toast } from "@/hooks/use-toast"

interface TaskProps {
    id:number
    title: string
    description: string
    type: 'TODO' | 'IN_PROGRESS' | 'COMPLETED'
  }

  export default function Task({id, title, description, type }: TaskProps) {
    const getTypeColor = (type: string) =&amp;gt; {
      switch (type) {
        case "TODO":
          return "bg-red-100 text-red-800"
        case "IN_PROGRESS":
          return "bg-green-100 text-green-800"
        case "COMPLETED":
          return "bg-blue-100 text-blue-800"
        default:
          return "bg-gray-100 text-gray-800"
      }
    }

    return (
        &amp;lt;div className="p-4 w-1/4  border rounded-lg hover:shadow-md transition-shadow group"&amp;gt;
        &amp;lt;div className="flex items-start justify-between gap-2"&amp;gt;
          &amp;lt;div className="flex-1"&amp;gt;
            &amp;lt;h3 className="font-medium text-lg"&amp;gt;{title}&amp;lt;/h3&amp;gt;
            &amp;lt;p className="mt-2 text-sm text-gray-600"&amp;gt;{description}&amp;lt;/p&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div className="flex items-start gap-2"&amp;gt;
            &amp;lt;span className={`px-2 py-1 rounded-full text-xs font-medium capitalize ${getTypeColor(type)}`}&amp;gt;{type}&amp;lt;/span&amp;gt;
            &amp;lt;div className="flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity"&amp;gt;
              &amp;lt;button
               onClick={()=&amp;gt;{}}
                className="p-1 text-gray-500 hover:text-gray-700 hover:bg-gray-100 rounded"
                aria-label="Edit task"
              &amp;gt;
                &amp;lt;Pencil className="w-4 h-4" /&amp;gt;
              &amp;lt;/button&amp;gt;
              &amp;lt;button
                onClick={()=&amp;gt;deleteTaskById(id).then((res)=&amp;gt;toast({title: "Success", description: "Task deleted successfully"})).catch((err)=&amp;gt;toast({title: "Error", description: "Something went wrong", variant: 'destructive'}))
              }
                className="p-1 text-gray-500 hover:text-red-600 hover:bg-red-50 rounded"
                aria-label="Delete task"
              &amp;gt;
                &amp;lt;Trash2 className="w-4 h-4" /&amp;gt;
              &amp;lt;/button&amp;gt;
            &amp;lt;/div&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    )
  }

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

&lt;/div&gt;



&lt;p&gt;We also use &lt;code&gt;revalidatePath&lt;/code&gt;, which is used to update the cache of a specific path.&lt;/p&gt;

&lt;p&gt;Here is the full code in the &lt;a href="https://github.com/khalidkhankakar/Blog-code/tree/main/server-actions" rel="noopener noreferrer"&gt;GitHub repo link here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy coding! 👍👍&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Building Reusable Components in React</title>
      <dc:creator>Khalid Kakar</dc:creator>
      <pubDate>Tue, 16 Jul 2024 06:40:43 +0000</pubDate>
      <link>https://dev.to/khalidkhankakar/building-reusable-components-in-react-4mj0</link>
      <guid>https://dev.to/khalidkhankakar/building-reusable-components-in-react-4mj0</guid>
      <description>&lt;p&gt;One of the greatest strengths of React is its component-based architecture, which allows developers to build modular and reusable pieces of UI. Reusable components not only save time but also ensure consistency across your application. In this blog post, we’ll explore the best practices for building reusable components in React and provide practical coding examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Build Reusable Components?
&lt;/h2&gt;

&lt;p&gt;Before diving into the code, let’s discuss why reusable components are important:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;- Consistency: Reusing components ensures a consistent look and feel across your application.&lt;/li&gt;
&lt;li&gt;- Maintainability: Isolating functionality in components makes your code easier to manage and update.&lt;/li&gt;
&lt;li&gt;- Efficiency: Building reusable components saves development time, as you can leverage existing components rather than creating new ones from scratch.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Start with Simple Components
&lt;/h3&gt;

&lt;p&gt;The first step in building reusable components is to identify UI elements that are used frequently across your application. Start by creating simple, self-contained components.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Button Component&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 PropTypes from 'prop-types';
import './Button.css';

const Button = ({ label, onClick, type = 'button' }) =&amp;gt; (
  &amp;lt;button className="btn" onClick={onClick} type={type}&amp;gt;
    {label}
  &amp;lt;/button&amp;gt;
);

Button.propTypes = {
  label: PropTypes.string.isRequired,
  onClick: PropTypes.func,
  type: PropTypes.oneOf(['button', 'submit', 'reset']),
};

export default Button;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Make Components Configurable
&lt;/h3&gt;

&lt;p&gt;To make components truly reusable, they should be configurable through props. This allows you to customize the appearance and behavior of the component without modifying its internal code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Configurable Button Component&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 PropTypes from 'prop-types';
import './Button.css';

const Button = ({ label, onClick, type = 'button', className = '', disabled = false }) =&amp;gt; (
  &amp;lt;button className={`btn ${className}`} onClick={onClick} type={type} disabled={disabled}&amp;gt;
    {label}
  &amp;lt;/button&amp;gt;
);

Button.propTypes = {
  label: PropTypes.string.isRequired,
  onClick: PropTypes.func,
  type: PropTypes.oneOf(['button', 'submit', 'reset']),
  className: PropTypes.string,
  disabled: PropTypes.bool,
};

export default Button;

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

&lt;/div&gt;



&lt;p&gt;Here, the Button component has additional props like className and disabled, making it more flexible and adaptable to different use cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Use Composition for More Complex Components
&lt;/h3&gt;

&lt;p&gt;Composition allows you to build complex components by combining simpler ones. This approach follows React's philosophy of breaking down UI into small, manageable pieces.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Card Component&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 PropTypes from 'prop-types';
import './Card.css';

const Card = ({ title, content, footer }) =&amp;gt; (
  &amp;lt;div className="card"&amp;gt;
    &amp;lt;div className="card-header"&amp;gt;{title}&amp;lt;/div&amp;gt;
    &amp;lt;div className="card-body"&amp;gt;{content}&amp;lt;/div&amp;gt;
    &amp;lt;div className="card-footer"&amp;gt;{footer}&amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
);

Card.propTypes = {
  title: PropTypes.node.isRequired,
  content: PropTypes.node.isRequired,
  footer: PropTypes.node,
};

export default Card;

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

&lt;/div&gt;



&lt;p&gt;In this example, the Card component is composed of title, content, and footer props, allowing you to pass any React elements to create a custom card layout.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Leverage Children for Greater Flexibility
&lt;/h3&gt;

&lt;p&gt;The children prop allows you to pass components and elements as children, providing greater flexibility in how your reusable components are used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Modal Component&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 PropTypes from 'prop-types';
import './Modal.css';

const Modal = ({ isOpen, onClose, children }) =&amp;gt; {
  if (!isOpen) return null;

  return (
    &amp;lt;div className="modal"&amp;gt;
      &amp;lt;div className="modal-content"&amp;gt;
        &amp;lt;button className="modal-close" onClick={onClose}&amp;gt;X&amp;lt;/button&amp;gt;
        {children}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

Modal.propTypes = {
  isOpen: PropTypes.bool.isRequired,
  onClose: PropTypes.func.isRequired,
  children: PropTypes.node,
};

export default Modal;

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

&lt;/div&gt;



&lt;p&gt;The Modal component uses the children prop to render any content passed to it, making it a highly flexible and reusable component for displaying modal dialogs.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Style Components Effectively
&lt;/h3&gt;

&lt;p&gt;Styling reusable components can be challenging, but using CSS-in-JS libraries like styled-components or Emotion can help manage styles in a modular way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Styled Button Component&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 styled from 'styled-components';

const StyledButton = styled.button`
  background-color: ${(props) =&amp;gt; (props.primary ? 'blue' : 'gray')};
  color: white;
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;

  &amp;amp;:hover {
    background-color: ${(props) =&amp;gt; (props.primary ? 'darkblue' : 'darkgray')};
  }
`;

const Button = ({ label, primary, onClick }) =&amp;gt; (
  &amp;lt;StyledButton primary={primary} onClick={onClick}&amp;gt;
    {label}
  &amp;lt;/StyledButton&amp;gt;
);

export default Button;

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

&lt;/div&gt;



&lt;p&gt;In this example, the StyledButton component uses styled-components to apply conditional styles based on the primary prop, providing a clean and modular approach to styling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Building reusable components in React is a powerful way to create maintainable, consistent, and efficient applications. By starting with simple components, making them configurable, leveraging composition and children, and using effective styling techniques, you can create a library of reusable components that will save you time and effort in your development process. Additionally, documenting your components with tools like Storybook ensures they are easy to understand and use by others.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>nextjs</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Optimizing Performance in React Applications</title>
      <dc:creator>Khalid Kakar</dc:creator>
      <pubDate>Sat, 13 Jul 2024 01:41:22 +0000</pubDate>
      <link>https://dev.to/khalidkhankakar/optimizing-performance-in-react-applications-59k0</link>
      <guid>https://dev.to/khalidkhankakar/optimizing-performance-in-react-applications-59k0</guid>
      <description>&lt;p&gt;As a React developer, ensuring that your applications run smoothly and efficiently is crucial for providing a great user experience. Performance optimization can make the difference between a fast, responsive app and one that feels sluggish. In this blog post, we'll explore several techniques to optimize performance in React applications, complete with code examples and real-world scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Use React's Built-in Performance Tools
&lt;/h2&gt;

&lt;p&gt;React provides built-in tools to help identify performance bottlenecks. The React Developer Tools extension for Chrome and Firefox allows you to inspect your React component tree, identify unnecessary re-renders, and analyze component performance.&lt;/p&gt;

&lt;p&gt;Example: React Developer Tools&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install the React Developer Tools extension from the Chrome Web Store or Firefox Add-ons.&lt;/li&gt;
&lt;li&gt;Open your React application and the developer tools.&lt;/li&gt;
&lt;li&gt;Navigate to the "Profiler" tab to start recording performance profiles.&lt;/li&gt;
&lt;li&gt;By analyzing the profiling data, you can pinpoint components that are causing performance issues and take steps to optimize them.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Avoid Unnecessary Re-Renders
&lt;/h2&gt;

&lt;p&gt;React's reconciliation process ensures that the DOM updates efficiently, but unnecessary re-renders can still degrade performance. To prevent this, you can use React.memo and shouldComponentUpdate.&lt;/p&gt;

&lt;p&gt;Example: Using React.memo&lt;br&gt;
jsx&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, { memo } from 'react';

const MyComponent = ({ data }) =&amp;gt; {
  console.log('Rendering MyComponent');
  return &amp;lt;div&amp;gt;{data}&amp;lt;/div&amp;gt;;
};

export default memo(MyComponent);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, MyComponent will only re-render if the data prop changes. Using React.memo can help reduce unnecessary renders and improve performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Optimize Component Rendering
&lt;/h2&gt;

&lt;p&gt;Sometimes, breaking down large components into smaller, reusable ones can improve performance by reducing the amount of work each render requires. Additionally, you can use techniques like code splitting and lazy loading to load only the necessary parts of your application.&lt;/p&gt;

&lt;p&gt;Example: Code Splitting with React.lazy&lt;br&gt;
jsx&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, { Suspense, lazy } from 'react';

const MyComponent = lazy(() =&amp;gt; import('./MyComponent'));

const App = () =&amp;gt; (
  &amp;lt;Suspense fallback={&amp;lt;div&amp;gt;Loading...&amp;lt;/div&amp;gt;}&amp;gt;
    &amp;lt;MyComponent /&amp;gt;
  &amp;lt;/Suspense&amp;gt;
);

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

&lt;/div&gt;



&lt;p&gt;In this example, MyComponent is loaded only when needed, reducing the initial load time of the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Optimize State Management
&lt;/h2&gt;

&lt;p&gt;Efficient state management is crucial for performance. Use local state only when necessary, and prefer using state management libraries like Redux or Zustand for more complex state management scenarios.&lt;/p&gt;

&lt;p&gt;Example: Using Zustand for State Management&lt;br&gt;
jsx&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import create from 'zustand';

const useStore = create((set) =&amp;gt; ({
  count: 0,
  increment: () =&amp;gt; set((state) =&amp;gt; ({ count: state.count + 1 })),
}));

const Counter = () =&amp;gt; {
  const { count, increment } = useStore();
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;span&amp;gt;{count}&amp;lt;/span&amp;gt;
      &amp;lt;button onClick={increment}&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;Zustand provides a lightweight and efficient way to manage state, helping to keep your components lean and performant.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Memoize Expensive Calculations
&lt;/h2&gt;

&lt;p&gt;If your components rely on expensive calculations, you can use useMemo to memoize these calculations and prevent them from being recomputed on every render.&lt;/p&gt;

&lt;p&gt;Example: Using useMemo&lt;br&gt;
jsx&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, { useMemo } from 'react';

const ExpensiveComponent = ({ items }) =&amp;gt; {
  const sortedItems = useMemo(() =&amp;gt; {
    console.log('Sorting items...');
    return items.sort((a, b) =&amp;gt; a - b);
  }, [items]);

  return (
    &amp;lt;ul&amp;gt;
      {sortedItems.map((item, index) =&amp;gt; (
        &amp;lt;li key={index}&amp;gt;{item}&amp;lt;/li&amp;gt;
      ))}
    &amp;lt;/ul&amp;gt;
  );
};

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

&lt;/div&gt;



&lt;p&gt;In this example, the sortedItems array is only recalculated when the items prop changes, reducing the computational overhead.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Throttle and Debounce Event Handlers
&lt;/h2&gt;

&lt;p&gt;Handling frequent events like scrolling or typing can cause performance issues. Throttling and debouncing event handlers can help mitigate this.&lt;/p&gt;

&lt;p&gt;Example: Using lodash's debounce&lt;br&gt;
jsx&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';
import debounce from 'lodash.debounce';

const SearchBar = () =&amp;gt; {
  const [query, setQuery] = useState('');

  const handleChange = debounce((event) =&amp;gt; {
    setQuery(event.target.value);
  }, 300);

  return &amp;lt;input type="text" onChange={handleChange} /&amp;gt;;
};

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

&lt;/div&gt;



&lt;p&gt;In this example, the handleChange function is debounced, meaning it will only be called 300 milliseconds after the user stops typing, reducing the number of unnecessary updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Optimize Images and Assets
&lt;/h2&gt;

&lt;p&gt;Large images and assets can slow down your application. Use tools like react-image and react-async-script-loader to optimize images and load scripts asynchronously.&lt;/p&gt;

&lt;p&gt;Example: Using react-image&lt;br&gt;
jsx&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 { Img } from 'react-image';

const OptimizedImage = ({ src, alt }) =&amp;gt; (
  &amp;lt;Img
    src={src}
    loader={&amp;lt;div&amp;gt;Loading...&amp;lt;/div&amp;gt;}
    unloader={&amp;lt;div&amp;gt;Failed to load image&amp;lt;/div&amp;gt;}
    alt={alt}
  /&amp;gt;
);

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

&lt;/div&gt;



&lt;p&gt;In this example, react-image helps optimize image loading by providing a loader and unloader, ensuring that your application remains responsive even with large images.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Optimizing performance in React applications involves a combination of techniques, from preventing unnecessary re-renders to optimizing state management and memoizing expensive calculations. By applying these strategies, you can ensure that your React applications are fast, responsive, and provide a great user experience.&lt;/p&gt;

&lt;p&gt;Remember, performance optimization is an ongoing process. Continuously monitor your applications using tools like the React Developer Tools and adjust your strategies as needed to maintain optimal performance.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>performance</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
