رفع اشکالات تند و زننده (درک مدال ها) – قسمت 1

اشکال زدایی یک باگ مزاحم در پروژه Next.js
هفته گذشته، من شروع به کار بر روی یک پروژه جدید کردم که اساساً با Next.js ساخته شده بود و با استفاده از کتابخانه مؤلفه Shadcn طراحی شده بود. در حین ساخت، با یک باگ آزاردهنده مواجه شدم که نه تنها سرعتم را کاهش داد، بلکه مرا وادار کرد تا در رویکرد خود برای اشکال زدایی و درک ابزارهایی که با آن کار می کنم تجدید نظر کنم.
چرا در این مورد بنویسید؟
هدف از نوشتن این مقاله این است که خودم را وادار کنم تا عمیقتر به درک عملکرد درونی اجزا و چارچوبها بپردازم. در گذشته، من کدی نوشته ام که به خوبی کار می کرد، اما وقت کافی برای درک عمیق آنچه را که نوشته ام نداشتم. این بار، میخواهم یک رویکرد سیستماتیک اتخاذ کنم تا مرا وادار کند تا عملکرد درونی چیزها را یاد بگیرم و هیچ چیز شما را مجبور به کاهش سرعت در هنگام کدنویسی یک اشکال کند. نوشتن در مورد آن به من کمک می کند تا سفرم را تامل کنم، یاد بگیرم و به اشتراک بگذارم.
رویکرد سیستماتیک به اشکال زدایی
برای حل این مشکل، فرآیند اشکال زدایی را به سه مرحله سیستماتیک تقسیم کردم:
- اشکال را تکرار کنید: به commit خاصی که در آن مشکل رخ داده است، برگردید، کد را بررسی کنید و به طور قابل اعتماد خطا را تکرار کنید.
- درک اینکه چرا این اشکال رخ می دهد: علت اصلی و تعامل بین اجزایی که منجر به مشکل شده است را تجزیه و تحلیل کنید.
- رفع اشکال: یک راه حل را اجرا کنید و آن را تأیید کنید.
این مقاله قدم اول را به تفصیل پوشش خواهد داد.
تکرار اشکال
این مولفه مشکل ساز است که باعث دردسر زیادی برای من شد:
قطعه کد: OrganizationDetailsModal
"use client";
import { motion } from "framer-motion";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogClose, DialogFooter } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import Image from "next/image";
import { useState } from "react";
const OrganizationDetailsModal: React.FC<OrganizationDetailsModalProps> = ({ hideModal, organization }) => {
const [open, setOpen] = useState(true);
const handleClose = () => {
hideModal();
setOpen(false);
};
return (
<Dialog
open={open}
onOpenChange={(isOpen) => {
if (!isOpen) {
handleClose();
}
}}
>
<DialogContent
onCloseAutoFocus={(e) => {
e.preventDefault();
const safeElement = document.getElementById("safe-focus-element");
if (safeElement) safeElement.focus();
}}
className="flex max-h-[80vh] w-[400px] flex-col rounded-xl bg-white px-5 py-4 overflow-y-auto"
>
<DialogHeader>
<div className="flex justify-between items-center">
<DialogTitle>Organisation DetailsDialogTitle>
<DialogClose asChild>
<button onClick={handleClose} className="text-gray-700 hover:text-gray-900">Xbutton>
DialogClose>
div>
DialogHeader>
<div className="space-y-4">
<div className="flex justify-between">
<span className="text-sm font-semibold">Organization Namespan>
<span className="text-sm">{organization.organizationName}span>
div>
div>
<DialogFooter>
<button onClick={handleClose} className="bg-primary-green text-white px-4 py-2 rounded-md">
Back
button>
DialogFooter>
DialogContent>
Dialog>
);
};
export default OrganizationDetailsModal;
قطعه کد: منوی کشویی
<DropdownMenu>
<DropdownMenuTrigger className="focus:outline-none">
<MoreHorizontal className="h-5 w-5 cursor-pointer" />
DropdownMenuTrigger>
<DropdownMenuContent align="start" sideOffset={4} className="rounded-md p-1 shadow-md">
{rowMenuItems.map((menuItem, menuIndex) => (
<DropdownMenuItem
key={menuIndex}
onClick={() => menuItem.onClick(row)}
className="flex justify-start gap-2 px-3 py-2 hover:bg-gray-100"
>
{menuItem.icon && <Image src={menuItem.icon} alt={menuItem.label} />}
<span>{menuItem.label}span>
DropdownMenuItem>
))}
DropdownMenuContent>
DropdownMenu>
کاری که این اجزا انجام می دهند
- منوی کشویی: هنگامی که روی آن کلیک می شود، این مؤلفه یک لیست کشویی از اقدامات را نمایش می دهد.
- مولفه گفتگو: این گفتگوی مودال با انتخاب یک عمل از منوی کشویی فعال می شود. اطلاعات دقیق را نمایش می دهد و یک دکمه بستن برای رد کردن آن دارد.
اشکال
هنگامی که روی منوی کشویی کلیک می شود، همانطور که انتظار می رود باز می شود. در داخل کشویی، گزینه ای برای مشاهده جزئیات وجود دارد که باعث می شود Dialog
جزء ظاهر شود مشکل زمانی رخ میدهد که گفتگو بسته میشود—هیچ چیز دیگری در صفحه پس از آن قابل کلیک نیست. این گیج کننده بود زیرا به نظر می رسید هر دو مؤلفه کاملاً مجزا کار می کنند.
سرخوردگی
علیرغم صرف چندین ساعت تحقیق، نتوانستم علت این موضوع را مشخص کنم. به نظر می رسد که تعامل بین مؤلفه های کشویی و محاوره ای نوعی ناسازگاری حالت یا مشکل DOM ایجاد می کند.
در نهایت، من تصمیم گرفتم یکی از قطعات را به طور کامل جایگزین کنم، که مشکل به طور موقت حل شد. با این حال، من بدون درک علت اصلی ناراضی ماندم، این همان چیزی است که قصد دارم بیشتر بررسی کنم.
نتیجه گیری
این قسمت اول سفر اشکالزدایی من را به پایان میرساند – تکرار اشکال و مستند کردن مشکل. در قسمت بعدی، من عمیقتر به عملکرد درونی این اجزا میپردازم تا بفهمم چه چیزی ممکن است باعث این رفتار غیرعادی شده باشد. با انجام این کار، من امیدوارم که بینشی به دست بیاورم که به من در رفع اشکالات مشابه در آینده کمک کند و به عنوان یک توسعه دهنده رشد کنم.
منتظر قسمت دوم باشید: درک اینکه چرا اشکال اتفاق می افتد.