افزودن قابلیت کشیدن و رها کردن به اپلیکیشن React – از صفر تا صد


قابلیت کشیدن و رها کردن (Drag and Drop) یکی از پراستفادهترین قابلیتها در وباپلیکیشنها محسوب میشود. این قابلیت یک روش شهودی برای دستکاری دادهها ارائه میکند. React یک کتابخانه عالی است که میتوان با استفاده از آن UI وب را ساخت و از این رو کتابخانههای با کیفیت بالایی به شکل کامپوننتهای ریاکت برای افزودن قابلیت Drag and Drop به اپلیکیشن React نوشته شدهاند.
کتابخانه react-beautiful-dnd از سوی Atlassian، سازنده سیستم مدیریت وظیفه JIRA طراحی شده است. این کتابخانه Drag and Drop یکی از سادهترین کتابخانهها برای گنجاندن در اپلیکیشن محسوب میشود.
در این مقاله یک لیست to-do میسازیم که از قابلیت Drag and Drop بهره میگیرد. در این مثال یک صفحه اصلی با یک فرم داریم که یک وظیفه در ابتدای صفحه ایجاد میشود، سپس در ادامه دو لیست به صورت کنار هم قرار دارند که لیست سمت چپ آیتم to-do را نمایش میدهد و لیست سمت راست نیز آیتمهای انجام یافته را نمیدهد. همچنین یک روش برای حذف وظیفه از هر یک از 2 لیست در اختیار کاربر قرار میگیرد. یک Redux store برای ذخیرهسازی کل لیست کارها مور استفاده قرار میگیرد.
برای شروع به ساخت اپلیکیشن، از یکی از سادهترین روشهای ممکن یعنی برنامه Create React App که فیسبوک ارائه کرده است کمک میگیریم. برای استفاده از آن باید دستور زیر را اجرا کنیم:
npx create-react-app todo-app
دستور فوق یک پوشه پروژه ایجاد میکند که کدهای اولیه اپلیکیشن نیز درون آن قرار دارند.
سپس برخی کتابخانههای مورد نیاز را نصب میکنیم. ما به یک کلاینت HTTP نیاز داریم، همچنین کتابخانههای react-beautiful-dnd، Bootstrap، Redux و React Router را نصب میکنیم. ما یک کلاینت HTTP برای ایجاد درخواستهای HTTP میسازیم. با استفاده از بوتاسترپ استایلبندی آسانی خواهیم داشت و از ریاکت روتر برای مسیریابی سمت کلاینت بهره خواهیم جست. دستور زیر را اجرا کنید تا همه کتابخانههای فوق نصب شوند:
npm i axios bootstrap react-bootstrap formik yup react-beautiful-dnd react-router-dom react-redux
از Axios به عنوان کلاینت HTTP خود استفاده میکنیم و Formik و Yup کتابخانههای اعتبارسنجی فرم هستند که میتوان به همراه React Bootstrap برای ذخیره موارد وارد شدن در فرم استفاده کرد.
زمانی که همه کتابخانههای فوق نصب شدند، میتوانیم شروع به نوشتن اپلیکیشن بکنیم. همه چیز را در پوشه src قرار میدهیم، مگر این که طور دیگری ذکر شده باشد. در آغاز یک فایل به نام actionCreator.js میسازیم و کد زیر را در آن قرار میدهیم:
سپس فایلی به نام action.js ایجاد میکنیم و کد زیر را در آن مینویسیم:
این دو فایل با همدیگر یک اکشن میسازند که به ریداکس استور که در ادامه خواهیم ساخت، ارسال میکنیم. سپس در فایل App.js کد موجود را با کد زیر تعویض میکنیم:
کد فوق یک نوار ناوبری در بخش فوقانی اضافه میکند و امکان نمایش مسیرهایی که در ادامه تعریف میکنیم را فراهم میسازد. صفحه اصلی فعلاً تنها مسیر است. در فایل HomePage.js کد زیر را مینویسیم:
این همان جایی است که منطق «کشیدن و رها کردن» قرار میگیرد. ما دو کامپوننت Droppable داریم که در آنها از 2 لیست برای ذخیره آیتمهای to-do و آیتمهای Done استفاده میکنیم. تنها دستگیره کشیدن و رها کردن که نیاز داریم، دستگیره onDragEnd است. این همان جایی است که فلگ done را برای آیتم وظیفه مرتبط با source که آیتم از آن کشیده شده است بهروزرسانی میکنیم. اگر از کامپوننت Droppable آیتمی را با مشخصه droppableId به نام todoDroppable بکشیم، در این صورت مقدار done را روی true تنظیم میکنیم. در غیر این صورت مقدار Done را روی false تعیین میکنیم. پس از انجام این کار، وظیفه را بهروزرسانی میکنیم و سپس آخرین وظایف را دریافت کرده و آنها را نمایش میدهیم. همچنین تابعی به نام removeTodo برای حذف یک وظیفه داریم. زمانی که وظیفهای حذف میشود، آخرین لیست از بکاند دریافت میشود. تابع setAllItems برای توزیع وظایف در لیستهای آیتمهای to-do و done استفاده میشود.
در تابع useEffect یک آرگومان دوم با آرایهای از tasks به عنوان آرگومان داریم. این آرایه برای هدفگیری یک callback به نام useEffect که در زمان تغییر یافتن tasks فراخوانی میشود، مورد استفاده قرار میگیرد. همین callback در صورتی که tasks با هر prop دیگر عوض شود، میتواند برای مدیریت هر تغییر prop دیگر نیزاستفاده شود.
در فایل HomePage.css کد زیر را مینویسیم:
این کد برای استایلبندی لیستها با افزودن مقداری فضابندی استفاده میشود. برای افزودن وظایف، یک کامپوننت اختصاصی به نام TaskForm برای اضافه کردن وظیفه داریم. فایلی به نام TaskForm.js ایجاد کرده و کد زیر را در آن قرار میدهیم:
اینک فرم افزودن وظیفه را به همراه اعتبارسنجی فرم داریم که بررسی میکند آیا توضیحات پر شدهاند یا نه. زمانی که وظیفه مجاز تلقی شد، آن را به بکاند تحویل میدهیم، سپس آخرین وظایف را دریافت کرده و در ریداکس استور ذخیره میکنیم. این همه کارهایی است که در تابع handleSubmit اجرا میشود. توجه داشته باشید که ما اینک شیء schema را با کتابخانه Yup ایجاد کردیم و سپس آن را به شیء validationSchema در کامپوننت Formik ارسال کردیم، در ادامه کامپوننت Formik تابع handleChange، شیء values و شیء errors را ارائه میکند که مستقیماً در فرم بوتاسترپ ریاکت استفاده میکنیم.
بدین ترتیب از نوشتن دستی همه کدهای دستگیرههای تغییر معاف میشویم. ضمناً باید || ‘’ را نیز در انتهای prop به نام values داشته باشیم تا prop به نام value همواره در حالت تعریف شده باقی بماند و از تحریک خطاهای ورودی ناخواسته جلوگیری شود. mapStateToProps در انتهای فایل، اقدام به نگاشت حالت tasks در store به props به نام tasks در کامپوننت میکند و mapDispatchToProps نیز تابع دیسپچ setTasks را نگاشت میکند که از آن برای بهروزرسانی store با وظایف بر اساس props کامپوننت TaskForm استفاده میکنیم.
سپس در فایل index.js کد موجود را با کد زیر عوض میکنیم:
بدین ترتیب اینک میتوانیم از ریداکس استور که در اپلیکیشن خود ایجاد کردیم، استفاده کنیم. سپس فایلی به نام reducers.js ایجاد کرده و کد زیر را اضافه میکنیم:
بنابراین میتوانیم وظایف خود را در این store ذخیره کنیم. سپس فایلی به نام requests.js میسازیم که برای ذخیرهسازی کد تابعها جهت ایجاد درخواستهای HTTP که ایجاد کردهایم استفاده میشود. کد زیر را در فایل بنویسید:
کدهای فوق امکان ایجاد عملیات CRUD را روی وظایف فراهم میسازند. این عملیات در HomePage و کامپوننت و TaskForm استفاده میشود. در ادامه کدهای موجود فایل public/index.html را با کد زیر عوض میکنیم:
ما در کد فوق، بوتاسترپ و CSS و آیکون Font Awesome را اضافه کردیم و از این رو میتوانیم از استایل بوتاسترپ استفاده کنیم و آیکون Close را که در تگ i مربوط به HomePage استفاده میشود، به دست میآوریم.
برای آغاز به کار بکاند، ابتدا پکیج json-server را با اجرای دستور زیر نصب میکنیم:
npm i json-server
سپس به پوشه پروژه میرویم و دستور زیر را اجرا میکنیم:
json-server --watch db.json
در فایل db.json، متن را به صورت زیر تغییر میدهیم:
بدین ترتیب یک نقطه انتهایی به نام tasks داریم که در requests.js تعریف شده است.
بدین ترتیب به پایان مقاله میرسیم.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای JavaScript (جاوا اسکریپت)
- مجموعه آموزشهای برنامهنویسی
- آموزش ری اکت (React) — مجموعه مقالات مجله فرادرس
- ساخت ویجت گفتگوی زنده با پشتیبانی در ری اکت (React) — از صفر تا صد
- ساخت صفحه انتخاب کاراکتر در React (بخش اول) — از صفر تا صد
==