متن خبر

چگونه با React، TailwindCSS و TypeScript یک دکمه شمارنده بسازیم

چگونه با React، TailwindCSS و TypeScript یک دکمه شمارنده بسازیم

شناسهٔ خبر: 640929 -




چگونه می توانید تعداد دفعاتی که کاربر روی یک دکمه کلیک می کند را پیگیری کنید؟ قلب ها در اینستاگرام یا لایک ها در فیس بوک چگونه شمارش می شوند؟

در این آموزش، دکمه ای می سازیم که تعداد دفعات کلیک روی یک دکمه را ردیابی می کند. در طول مسیر، برخی از مفاهیم اساسی در React مانند کامپوننت، JSX، انتقال props بین کامپوننت ها و مدیریت حالت با هوک ها را خواهید آموخت. همچنین با Tailwind و TypeScript آشنا خواهید شد.

این آموزش مبتنی بر مثال‌ها و مفاهیمی است که در بخش «Learn» از مستندات React، که می‌توانید در اینجا پیدا کنید، توضیح داده شده است.

پیش نیازها

آشنایی اولیه با جاوا اسکریپت، مانند کار با متغیرها، توابع، آرایه ها و اشیاء.

آشنایی اولیه با CSS و HTML

آشنایی اولیه با خط فرمان

گره نصب شده است.

یک ویرایشگر کد به انتخاب شما (من در اینجا از Visual Studio Code استفاده خواهم کرد)

فهرست مطالب

    نحوه ساخت دکمه شمارنده

    نحوه بازسازی پروژه

    دو جزء با دولت مستقل و مشترک

    چگونه هر دو جفت دکمه را به وب سایت خود اضافه کنیم

    نحوه استقرار سایت در Netlify

فصل 1: نحوه ساخت دکمه شمارنده

React چیست؟

قبل از غواصی، اجازه دهید React را تعریف کنیم. React یک کتابخانه جاوا اسکریپت برای ایجاد رابط کاربری از قطعاتی به نام کامپوننت است. کامپوننت ها توابع جاوا اسکریپت هستند که می توانند داده ها را به صورت تعاملی برای کاربران شما دریافت و نمایش دهند.

راه اندازی پروژه

ما از Next.js برای راه اندازی React محلی خود استفاده خواهیم کرد.

در پوشه ای که می خواهید این پروژه را ذخیره کنید، ترمینال خود را باز کنید و دستور زیر را اجرا کنید:

 npx create-next-app@latest
Next.js را نصب کنید

نام پروژه خود را هر طور که دوست دارید نامگذاری کنید و به دستورات زیر پاسخ دهید:

 What is your project named? react-counter-button Would you like to use TypeScript? Yes Would you like to use ESLint? Yes Would you like to use Tailwind CSS? Yes Would you like to use `src/` directory? No Would you like to use App Router? (recommended) Yes Would you like to customize the default import alias (@/*)? No
پیکربندی پروژه Next.js

حالا بیایید cd وارد فهرست پروژه خود کنیم

 cd react-counter-button
حرکت به دایرکتوری پروژه ما

و پروژه را با کد ویژوال استودیو اجرا کنید:

 code .
باز کردن پروژه ما در Visual Studio Code از خط فرمان

توجه: اگر دستور code در PATH خود ندارید، می‌توانید ⇧⌘P (Ctrl+Shift+P در ویندوز/لینوکس) را فشار دهید و عبارت Shell Command را تایپ کنید: دستور «code» را در PATH نصب کنید. همچنین، می‌توانید پوشه را روی نماد Visual Studio Code در MacOS بکشید. یا، در کد ویژوال استودیو، می توانید File -> Open را انتخاب کنید و "react-counter-button" یا نام پروژه خود را پیدا کنید.

در اجرای ترمینال شما:

 npm run dev
اجرای محیط توسعه ما

مرورگر خود را به localhost:3000 باز کنید و باید صفحه زیر را ببینید:

اسکرین شات-2023-10-14-at-7.10.35-PM
Next.js boilerplate

ما اکنون پروژه را در دست اجرا داریم. با بازگشت به ویرایشگر کد خود، می‌توانیم کار را شروع کنیم.

دیگ بخار را بردارید

در app/page.tsx ، بیایید بیشتر کد boilerplate را به جز دو تگ main حذف کنیم. سپس یک عنوان برای پروژه خود در یک تگ h1 در بین تگ های main اضافه می کنیم. کد ما باید به شکل زیر باشد:

 export default function Home() { return ( <main className="flex min-h-screen flex-col items-center justify-between p-24"> <h1>React Counter Button</h1> </main> ); }
حذف دیگ بخار

در اینجا چیزی است که اکنون باید ببینیم:

اسکرین شات-2023-10-16-at-8.22.30-PM
وضعیت اولیه پروژه ما

نوشتن اولین جزء ما

بیایید اولین مؤلفه خود را ایجاد کنیم. کامپوننت React تابعی است که نشانه گذاری را برمی گرداند. در زیر و خارج از محدوده عملکرد Home خود، بیایید موارد زیر را بنویسیم:

 function Button() { return <button>I have been clicked X times</button>; }
اولین جزء ما، دکمه

در اینجا ما یک تابع Button داریم که مقداری نشانه گذاری را در JSX برمی گرداند. JSX شباهت زیادی به HTML دارد، اما می‌تواند محتوای پویا را نمایش دهد و قوانین سخت‌تری نسبت به HTML دارد. می‌توانید درباره JSX در اسناد React اینجا اطلاعات بیشتری کسب کنید.

تابع Button باید با حروف بزرگ باشد تا به عنوان یک مؤلفه معتبر React شناخته شود. این آن را با یک تگ HTML، که حروف کوچک است، در تضاد قرار می دهد.

متوجه خواهید شد که ما هنوز هیچ تغییری در صفحه وب خود نمی بینیم - برای دیدن آن روی صفحه باید این مؤلفه را رندر کنیم.

ما می‌توانیم از کامپوننت Button به‌گونه‌ای استفاده کنیم که انگار یک تگ HTML است که ما ایجاد کرده‌ایم. اگر مؤلفه Button را در مولفه Home قرار دهیم، باید آن را روی صفحه ببینیم:

 export default function Home() { return ( <main className="flex min-h-screen flex-col items-center justify-between p-24"> <h1>React Counter Button</h1> <Button /> </main> ); } function Button() { return <button>I have been clicked X times</button>; }
تودرتو کردن مؤلفه Button در مؤلفه Home
اسکرین شات-2023-10-20-at-6.37.57-PM
رندر کردن مولفه Button (با CSS کمتر از ایده آل)

طراحی اولین کامپوننت خود را با Tailwind

متوجه خواهید شد که دکمه در پایین صفحه است. این به این دلیل است که سبک های main شامل justify-between در جهت flex-col هستند. اگر justify-between را حذف کنیم باید این را ببینیم:

اسکرین شات-2023-10-20-at-6.36.57-PM
بهبود CSS از وضعیت اولیه برنامه ما

می‌توانید درباره تراز کردن آیتم‌ها در فلکس‌باکس از MDN اینجا بیشتر بخوانید.

همچنین متوجه خواهید شد که دکمه بدون استایل است. این به این دلیل است که Tailwind استایل های پیش فرض دکمه ها را به عنوان بخشی از سبک های "پیش از پرواز" حذف می کند. اگر کنجکاو هستید که ببینید این سبک‌ها از کجا آمده‌اند، می‌توانید node_modules/tailwindcss/src/css/preflight.css را باز کنید و خط 193 را تحلیل کنید (لینک دائمی در GitHub در اینجا ):

 /* 1. Correct the inability to style clickable types in iOS and Safari. 2. Remove default button styles. */ button, [type='button'], [type='reset'], [type='submit'] { -webkit-appearance: button; /* 1 */ background-color: transparent; /* 2 */ background-image: none; /* 2 */ }
دلیل اینکه TailwindCSS به طور پیش فرض دکمه های سبک ندارد

ما قرار نیست استایل ها را در node_modules تغییر دهیم - در عوض استایل خود را به مولفه Button اضافه می کنیم. یکی از مزایای Tailwind این است که CSS ما با جاوا اسکریپت ما قرار می گیرد و تغییرات سریع در سبک ها را آسان تر از باز کردن یک فایل شیوه نامه جداگانه می کند.

بیایید تغییرات زیر را ایجاد کنیم:

 export default function Home() { return ( <main className="flex min-h-screen flex-col items-center p-24 gap-4"> <h1>React Counter Button</h1> <Button /> </main> ); } function Button() { return ( <button className="bg-blue-500 hover:bg-blue-700 rounded text-white font-bold px-4 py-2"> I have been clicked X times </button> ); }
حالت دادن به جزء Button ما

ما استایل‌هایی را به دکمه‌مان اضافه کرده‌ایم، و همچنین یک gap-4 به جعبه انعطاف‌پذیر main خود اضافه کرده‌ایم تا فاصله‌ای بین h1 و button ایجاد کنیم. (شما می توانید اطلاعات بیشتری در مورد "شکاف" ویژگی CSS در MDN در اینجا بخوانید.) اکنون باید این را ببینیم:

اسکرین شات-2023-10-20-at-6.49.22-PM
مشاهده مؤلفه Button استایل ما

صبر کنید، اما Tailwind چیست؟

اکنون که مؤلفه دکمه‌مان را استایل‌بندی کرده‌ایم و موارد را با فاصله از یکدیگر جدا کرده‌ایم، بیایید به این فکر کنیم که Tailwind چیست و چه چیزی برای ما فراهم کرده است. Tailwind یک فریمورک CSS است که مجموعه ای از کلاس های "کاربردی" را ارائه می دهد که می توانیم برای استایل دادن به هر عنصر از آنها استفاده کنیم.

اما کلاس کاربردی چیست؟ خواهید دید که برای استایل دادن به دکمه خود، کلاس هایی مانند bg-blue-500 را اضافه کرده ایم - که مربوط به تنظیم ویژگی background-color آبی و rounded - که مربوط به border-radius: 0.25rem است.

هر کلاس با توجه به کاربرد آن تعریف می شود: تغییر رنگ پس زمینه، شعاع حاشیه، و غیره. از طریق گفت ن این کلاس های کاربردی به عناصر خود، به سبک های مورد نظر خود می رسیم.

Tailwind برخلاف سایر فریم ورک‌ها مانند Bootstrap قرار می‌گیرد که کلاس‌های از پیش تعریف‌شده‌ای را برای عناصری مانند دکمه‌ها ارائه می‌کند. در بوت استرپ، یک کلاس از btn را برای دستیابی به یک دکمه استایل اضافه می کنیم. و البته، با CSS استاندارد، احتمالاً یک کلاس سفارشی (شاید به نام button ) به عنصر خود اضافه می کنیم و مجموعه قوانین CSS را در یک شیوه نامه جداگانه ایجاد می کنیم.

در بازگشت به پروژه خود، تا کنون یک پروژه React را با استفاده از Next.js راه‌اندازی کرده‌ایم، اولین مؤلفه React خود را ایجاد کرده‌ایم و دکمه‌مان را با استفاده از Tailwind استایل داده‌ایم. چگونه عملکرد پیشخوان را معرفی کنیم؟

نحوه اضافه کردن حالت

برای نمایش تعداد دفعاتی که یک دکمه کلیک شده است، باید از یک رویداد کنترل کننده استفاده کنیم و به راهی برای مدیریت وضعیت نیاز داریم.

وضعیت حافظه مختص مولفه است. در مثال ما، اینگونه است که دکمه چند بار کلیک شده را به خاطر می آورد. با استفاده از یک تابع React ویژه " قلاب "، ما یک رندر مجدد را راه اندازی می کنیم و داده ها را در سراسر رندرها حفظ می کنیم - قلاب useState توسط React برای این منظور ارائه شده است.

در بالای page.tsx ما، بیایید useState وارد کنیم:

import { useState } from "react"

و در کامپوننت Button خود، بیایید موارد زیر را اضافه کنیم:

 function Button() { const [count, setCount] = useState(0) return ( <button className="bg-blue-500 hover:bg-blue-700 rounded py-2 px-4 text-white font-bold"> I have been clicked X times </button> ); }
اضافه کردن useState به جزء Button ما

بیایید چیزهایی را که در اینجا داریم باز کنیم:

ما از تخصیص تخریب ساختار برای دریافت مقادیر count و تابع setCount از useState استفاده می کنیم. قرارداد این است که این دو مقدار را something و setSomething نامگذاری کنیم، اگرچه می‌توانیم هر چیزی نامگذاری کنیم.

آرگومان useState مقدار اولیه متغیر حالت ما است. در اینجا ما آن را روی 0 قرار داده ایم.

count وضعیت فعلی م است.

setCount تابعی است که وضعیت ما را به روز می کند و یک رندر مجدد را راه اندازی می کند.

با این حال، اگر روی ذخیره کلیک کنید، خطای زیر را در ترمینال و مرورگر خود مشاهده خواهید کرد:

 You're importing a component that needs useState. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default. Learn more: https://nextjs.org/docs/getting-started/react-essentials ╭─[/[...your project path]/src/app/page.tsx:1:1] 1 │ import { useState } from "react"; · ──────── 2 │ 3 │ export default function Home() { 4 │ return ( ╰──── Maybe one of these should be marked as a client entry with "use client": ./src/app/page.tsx
خطا در عدم تعیین "use Client" هنگام استفاده از useState

این به دلیل استفاده Next.js از React Server Components است که می‌توانید در اینجا بیشتر در مورد آن بیاموزید. React Server Components موضوع بزرگی است، اما نکته اصلی این است که، به طور پیش‌فرض، مؤلفه‌ها در Next.js مؤلفه‌های سرور هستند و useState فقط در یک مؤلفه مشتری کار می‌کند. اگر دستور "use client" را در بالای page.tsx خود بنویسیم، خطا را برطرف می کنیم.

نحوه ارزیابی جاوا اسکریپت در JSX

اگر روی دکمه کلیک کنیم، باز هم به‌روزرسانی اعداد را نمی‌بینیم. این به این دلیل است که ما به راهی برای درون یابی (یا ارزیابی) جاوا اسکریپت در نشانه گذاری JSX خود نیاز داریم. پرانتزهای فرفری را وارد کنید: {} .

می‌توانیم از بریس‌های فرفری برای «فرار» به جاوا اسکریپت از داخل نشانه‌گذاری JSX استفاده کنیم. به این ترتیب می توانیم عبارات جاوا اسکریپت (مانند گفت ن به شمارنده) را ارزیابی کرده و داده ها را به صورت پویا در اجزای خود نمایش دهیم. در اینجا کاری است که ما انجام خواهیم داد:

 function MyButton() { const [count, setCount] = useState(0); return ( <button className="bg-blue-500 hover:bg-blue-700 rounded py-2 px-4 text-white font-bold"> I have been clicked {count} times </button> ); }
ارزیابی {count} در مولفه Button

ما {count} را برای ارزیابی مقدار count از useState در دکمه خود اضافه کرده‌ایم. باید موارد زیر را ببینیم:

اسکرین شات-2023-11-26-at-4.46.56-PM
نمایش داده ها در JSX با بریس های مجعد {}

ما یک 0 را می بینیم - این از متغیر count است که ما از قلاب useState خود تخریب کردیم، که در ابتدا آن را 0 تنظیم کردیم. ما با موفقیت جاوا اسکریپت را در نشانه گذاری JSX خود درون یابی کردیم!

رسیدگی به رویداد

متوجه خواهید شد که اگر روی دکمه کلیک کنیم، باز هم هیچ اتفاقی نمی افتد. وقتی روی آن کلیک می کنیم چگونه عدد را افزایش دهیم؟

برای این کار، از تابع کنترل کننده رویداد و همچنین تابع تنظیم کننده (که نام آن را setCount گذاشتیم) که از useState دریافت می کنیم، استفاده خواهیم کرد:

 function MyButton() { const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); } return ( <button className="bg-blue-500 hover:bg-blue-700 rounded py-2 px-4 text-white font-bold"> I have been clicked {count} times </button> ); }
تعریف تابع handleClick ما

کاری که ما در اینجا انجام دادیم اضافه کردن یک تابع handleClick برای به روز رسانی وضعیت متغیر count است. قرارداد این است که handle توابع کنترل کننده رویداد را به همراه نام رویداد خود نامگذاری کنید (به عنوان مثال، handleClick ).

setCount یک تابع set ویژه است که توسط useState برگردانده شده است که وضعیت متغیر count را به هر چیزی که به عنوان آرگومان ارسال می کنیم به روز می کند. برای مثال، ما می‌توانیم setCount(2) صدا بزنیم و count آن را به 2 به‌روزرسانی می‌کند. setCount(7) آن را روی 7 تنظیم می‌کند و غیره.

ما setCount(count + 1) را فراخوانی می کنیم که به setCount(0 + 1) می رسد، زیرا مقدار اولیه count 0 است. با کلیک بعدی، count 1 خواهد بود، پس ما setCount(1 + 1) را فراخوانی می کنیم. setCount(1 + 1) ، و کلیک بعدی setCount(2 + 1) و غیره را فراخوانی می کند.

این به ما امکان می دهد با هر کلیک شمارنده را به روز کنیم. اما، اگر کلیک کنید، متوجه می شوید که هنوز هیچ اتفاقی نمی افتد - چرا؟ شاید یک لحظه وقت بگذارید و سعی کنید قبل از خواندن ادامه مطلب، این موضوع را خودتان بفهمید تا به این مفهوم کمک کنید که حتی بهتر بماند.

چگونه یک رویداد Handler را به عنوان یک ابزار به JSX خود منتقل کنید

با نگاهی به کد ما، هیچ رابطه ای بین کلیک کاربر روی دکمه و تابع handleClick وجود ندارد. باید کنترل کننده رویداد handleClick را به ویژگی onClick روی دکمه منتقل کنیم! بیایید اضافه کنیم که در اینجا:

 function MyButton() { const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); } return ( <button onClick={handleClick} className="bg-blue-500 hover:bg-blue-700 rounded py-2 px-4 text-white font-bold" > I have been clicked {count} times </button> ); }
انتقال handleClick به عنوان یک پایه به Button

توجه کنید که چگونه onClick={handleClick()} را نگفته‌ایم. ما خودمان تابع را در اینجا فراخوانی نمی کنیم، بلکه در عوض آن را منتقل می کنیم. این یک تمایز مهم است، زیرا React زمانی که کاربر روی دکمه کلیک می‌کند، به جای شلیک فوری، این تابع را برای ما فراخوانی می‌کند.

در اینجا می‌توانید درباره انتقال عناصر به مؤلفه‌ها در اسناد React اطلاعات بیشتری کسب کنید.

پروژه کاری ما

اکنون آن را امتحان کنید، دکمه کار می کند!

اکنون دکمه ای دارید که با کلیک روی آن، تعداد آن را به روز می کند. این نشان‌دهنده استفاده از درون‌یابی جاوا اسکریپت در JSX با استفاده از بریس‌های فرفری، ایجاد کامپوننت خود و قرار دادن آن در اجزای دیگر، استفاده از حالت و هوک‌ها در React، و همچنین کار با Next.js و Tailwind است. تبریک می گویم!

واکنش ضد دکمه
پروژه کاری ما

در اینجا یک نکته خوب برای انجام تغییرات ما با استفاده از Git است. شما می توانید فرآیند ترمینال فعلی را با فشار دادن ctrl + c ببندید و سپس git add . ، به دنبال آن git commit -m "counter button" یا پیام دیگری که معنادار است.

فصل 2: ​​چگونه پروژه را بازسازی کنیم

انتقال کامپوننت ما به فایل دیگری

همانطور که پروژه ما نشسته است، تمام کدها در app/page.tsx هستند. اگر بخواهیم یک جزء دیگر یا چندین جزء اضافه کنیم چه؟ با گذشت زمان، page.tsx ما بزرگ و خواندن آن دشوار می شود.

در عوض، ما می‌توانیم اجزای خود را به فایل‌های خود تقسیم کنیم تا به خوانایی و همچنین ماژولار بودن (استفاده مجدد از مؤلفه در چندین مکان مختلف) کمک کنیم.

بیایید با ایجاد یک components پوشه در ریشه پروژه خود شروع کنیم تا اجزای خود را ذخیره کنیم. در داخل components ، فایلی به نام button.tsx ایجاد کنید. سپس، در app/page.tsx کل مؤلفه تابع Button را برش دهید (کپی و سپس حذف کنید) و آن را در components/button.tsx قرار دهید.

components/button.tsx باید به شکل زیر باشد:

 function Button() { const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); } return ( <button onClick={handleClick} className="bg-blue-500 hover:bg-blue-700 rounded text-white font-bold px-4 py-2" > I have been clicked {count} times </button> ); }
components/button.tsx

خطای useState import را برطرف کنید

احتمالاً در ویرایشگر کد خود متوجه خواهید شد که useState(0) دارای خطوط موزون قرمز زیر آن است. در Visual Studio Code، اگر ماوس را روی آن نگه دارید، با خطایی مواجه می شوید که می گوید:

اسکرین شات-2024-06-07-at-6.10.44-PM
خطا: نمی توان نام "useState" را پیدا کرد

چرا این هست؟ ما از useState استفاده می کنیم اما ماژول را از React وارد نکرده ایم. گفت ن import { useState } from "react"; به بالای فایل button.tsx ما این خطا را برطرف می کند.

اگر به ابتدای تابع نگاه کنید، خواهید دید که Button() با خطوط سفید در کد ویژوال استودیو خط کشیده شده است. نگه داشتن ماوس روی آن این خطا را نشان می دهد. فکر کنید که چرا ممکن است این مورد باشد - ما بعداً به این موضوع خواهیم پرداخت.

اسکرین شات-2024-06-07-at-6.13.45-PM
خطا: "دکمه" اعلام شده است اما مقدار آن هرگز خوانده نمی شود

واردات و صادرات قطعات

بیایید به app/page.tsx برگردیم. در اینجا دو خطا مشاهده خواهید کرد: یکی در import { useState } from "react"; و دیگری در <Button /> .

بیایید ابتدا به خطای useState بپردازیم. ما useState در کامپوننت Button خود استفاده کردیم، اما اکنون که آن مؤلفه را به فایل خودش منتقل کردیم، دیگر آن را نداریم. با حذف آن خطای ما حل می شود. می توانید از cmd (ctrl on Windows) + shift + k برای حذف کل خط در Visual Studio Code استفاده کنید.

اگر app/page.tsx خود را ذخیره کرده باشید، این خطا را در کنسول خواهید دید:

 ⨯ app/page.tsx (7:14) @ Button ⨯ ReferenceError: Button is not defined at Home (./app/page.tsx:19:89) digest: "2129895745" 5 | <main className="flex min-h-screen flex-col items-center p-24 gap-4"> 6 | <h1>React Counter Button</h1> > 7 | <Button /> | ^ 8 | </main> 9 | ); 10 | } GET / 500 in 87ms
ReferenceError: دکمه تعریف نشده است

چرا Button تعریف نمی شود؟ مسئله این است که در app/page.tsx ما هیچ راهی برای دسترسی به مؤلفه Button در components/button.tsx نداریم. ما این مشکل را با صادرات و وارد کردن ماژول مناسب حل می کنیم.

در داخل components/button.tsx ، در ابتدای اعلان تابع خود، بیایید کلمات کلیدی export default اضافه کنیم. فایل اکنون به شکل زیر خواهد بود:

 import { useState } from "react"; export default function Button() { const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); } return ( <button onClick={handleClick} className="bg-blue-500 hover:bg-blue-700 rounded text-white font-bold px-4 py-2" > I have been clicked {count} times </button> ); }
components/button.tsx

متوجه خواهید شد که خطای قبلی 'Button' is declared but its value is never read از بین رفته است، زیرا اکنون مقدار به عنوان یک صادرات پیش فرض خوانده می شود.

اما ما اینجا چه کرده ایم؟ صادرات یا صادرات پیش فرض چیست؟ صادرات و وارد کردن به ما این امکان را می دهد که اجزای جاوا اسکریپت را در بخش های خود مدولار کنیم و از آنها در سایرین استفاده کنیم.

دو نوع وجود دارد: صادرات پیش‌فرض و صادرات با نام . هر فایل می‌تواند چندین صادرات با نام داشته باشد اما فقط یک صادرات پیش‌فرض داشته باشد. در اینجا می توانید اطلاعات بیشتری در مورد واردات و صادرات مؤلفه ها در اسناد React بخوانید.

اکنون که مؤلفه را از components/button.tsx صادر کردیم، باید آن را در app/page.tsx وارد کنیم. کد ویژوال استودیو می‌تواند به پیشنهادات " intellisense " کمک کند: در بالای فایل، اگر شروع به تایپ کردن "Button" کنید، وارد کردن صحیح با مسیر فایل صحیح را پیشنهاد می‌کند:

import Button from "@/components/button";

در Next.js می‌توانیم از این دستور @/ برای ارجاع به ریشه پروژه استفاده کنیم. در صورتی که وارد کردن ما چندین لایه فایل عمیق باشد، این یک راحتی است. می‌توانید نمونه‌های نحو @/ را در مستندات Next.js در اینجا بخوانید.

خواهید دید که خطاهای ما ناپدید شده اند و پروژه همچنان کار می کند! ما هیچ ویژگی جدیدی اضافه نکرده‌ایم، اما کد خود را با موفقیت بازسازی کرده‌ایم تا آن را مدولارتر، خواناتر و قابل نگهداری‌تر کنیم.

در اینجا بیایید همان مراحل را دنبال کنیم تا تغییرات خود را انجام دهیم و پیامی مانند refactor: move button to its own file .

فصل 3: دو جزء با دولت مستقل و مشترک

دو مولفه با دولت مستقل

اگر بخواهیم دو دکمه داشته باشیم که مستقل از یکدیگر بشمارند چه؟ این زیبایی React را به نمایش می گذارد و پیاده سازی توسعه مبتنی بر کامپوننت ساده تر از ساخت مجدد دکمه از ابتدا خواهد بود.

در app/page.tsx می‌توانیم به سادگی <Button /> دیگری اضافه کنیم. می توانید مکان نما خود را روی <Button /> متمرکز کنید و option + shift + ↓ را فشار دهید تا یک <Button /> دیگر ایجاد کنید:

 "use client"; import Button from "@/components/button"; export default function Home() { return ( <main className="flex min-h-screen flex-col items-center p-24 gap-4"> <h1>React Counter Button</h1> <Button /> <Button /> </main> ); }
app/page.tsx

اکنون باید دو دکمه شمارنده با حالت مستقل خود را ببینید:

اسکرین شات-2024-06-07-at-6.40.47-PM
دو دکمه با حالت مستقل

طراحی مبتنی بر کامپوننت با React استفاده مجدد از بخش‌هایی از برنامه شما را آسان می‌کند. برد آسان

دو جزء با حالت مشترک

اگر بخواهیم دکمه‌ها وضعیت خود را به اشتراک بگذارند و با هم به‌روزرسانی شوند، چه؟ متوجه خواهید شد که وقتی روی هر دکمه کلیک می کنیم، آنها به طور جداگانه افزایش می یابند.

برای اینکه دکمه‌ها حالت خود را به اشتراک بگذارند، باید وضعیت آن‌ها را از هر مؤلفه جداگانه به «بالا» به مؤلفه والد مشترکشان منتقل کنیم (در این مورد، تابع Home در app/page.tsx ). شما همچنین می شنوید که به عنوان " حالت بلند کردن " نامیده می شود.

منطق شمارش را از components/button.tsx برش دهید و آن را در app/page.tsx در بدنه تابع Home قرار دهید. همچنین به واردات useState در بالای فایل نیاز داریم:

 "use client"; import { useState } from "react"; import Button from "@/components/button"; export default function Home() { const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); } return ( <main className="flex min-h-screen flex-col items-center p-24 gap-4"> <h1>React Counter Button</h1> <Button /> <Button /> </main> ); }
app/page.tsx

انتقال Props به یک کامپوننت

اکنون که وضعیت خود را در مؤلفه والد هر دکمه ( Home ) داریم، می‌توانیم این حالت را از طریق props به مؤلفه Button منتقل کنیم. ما قصد داریم هم کنترل کننده رویداد handleClick و هم متغیر count که قصد داریم نمایش دهیم، منتقل کنیم:

 "use client"; import { useState } from "react"; import Button from "@/components/button"; export default function Home() { const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); } return ( <main className="flex min-h-screen flex-col items-center p-24 gap-4"> <h1>React Counter Button</h1> <Button count={count} onClick={handleClick} /> <Button count={count} onClick={handleClick} /> </main> ); }
انتقال لوازم به جزء ما

count از useState به count prop و تابع handleClick به onClick prop هر دو در مولفه Button ارسال می شود. در JSX، ما می‌توانیم آپشن های خود را تعریف کنیم (که ممکن است شما را به یاد آپشن های HTML بیاندازد) تا بتوانیم داده‌ها را از یک مؤلفه به مؤلفه دیگر منتقل کنیم.

ممکن است در این مرحله برخی از خطاهای مربوط به TypeScript را مشاهده کنید - ما بعداً به آنها باز خواهیم گشت.

Props را در مؤلفه فرزندتان بخوانید

اکنون که داده‌ها را به‌عنوان props به مؤلفه خود منتقل کرده‌ایم، باید مؤلفه Button خود را طوری تنظیم کنیم که props را از مؤلفه اصلی خود بخواند . درون components/button.tsx :

 export default function Button({ count, onClick }) { return ( <button onClick={onClick} className="bg-blue-500 hover:bg-blue-700 rounded text-white font-bold px-4 py-2" > I have been clicked {count} times </button> ); }

اجزای تابع React یک شی props را به عنوان آرگومان می پذیرند. در اینجا ما ابزارهایی را که می‌خواهیم به مؤلفه Button منتقل کنیم، تخریب می‌کنیم. به عبارت دیگر، count و onClick مستقیماً از شی props به عنوان آرگومان برای Button می گیریم.

اگر فایل خود را ذخیره کنید، خواهید دید که اکنون کار می کند: شما دو دکمه با حالت اشتراکی دارید:

Screen-Recording-2024-06-14-at-12.07.37-PM
دو دکمه با حالت مشترک

اما چرا onClick به کامپوننت Button منتقل نکردیم و آن را handleClick نکردیم؟ آیا وقتی روی دکمه کلیک می کنیم، handleClick همان چیزی نیست که قصد داریم اجرا کنیم؟

در مولفه Home در app/page.tsx ، ما handleClick تعریف می کنیم و آن را به عنوان یک پایه به مولفه Button منتقل می کنیم. در داخل بدنه مولفه Button در components/button.tsx ما prop onClick می خوانیم، نه خود handleClick کنترل کننده رویداد. پس وقتی کامپوننت Button فعال می‌شود، پایه onClick فراخوانی می‌کند، که "بالا" درخت مؤلفه داخل Home قرار می‌گیرد، جایی که سپس handleClick فراخوانی می‌کند، شمارش را به‌روزرسانی می‌کند و سپس آن حالت را به هر دو مؤلفه Button منتقل می‌کند.

دوره کوچک تصادف در TypeScript

اگر components/button.tsx را تحلیل کنید، خطاهای زیر را هم برای count و هم برای برپایی onClick که در Button می‌خوانید مشاهده خواهید کرد:

اسکرین شات-2024-06-14-at-2.49.55-PM
عنصر Binding 'count' به طور ضمنی دارای یک نوع 'هرگونه' است.

(شما می توانید این خطاهای "زیبا" برجسته شده در نحو TypeScript را با پسوند Visual Studio Code در اینجا دریافت کنید).

این خطاها به چه معنا هستند و TypeScript چیست؟ TypeScript ابر مجموعه ای از جاوا اسکریپت است که انواع را به جاوا اسکریپت اضافه می کند. اینها می توانند به ما کمک کنند تا مطمئن شویم که برنامه ما همانطور که قصد داریم کار می کند. نمونه هایی از انواع عبارتند از number , boolean , و string . این خطا به ما می گوید که ما یک نوع برای count props یا onClick تعریف نکرده ایم.

پس نوع count چگونه خواهد بود؟ اگر نتیجه شمارش را در نظر بگیریم، پاسخ ها می تواند 1 ، 2 ، 3 و غیره باشد. اینها همه اعداد هستند، پس ما نوع number برای count اختصاص می دهیم.

onClick prop تابعی است که هیچ آرگومان یا مقداری برمی‌گرداند - ما از آن برای اثر جانبی به‌روزرسانی setCount استفاده می‌کنیم. پس نوع () => void را به آن اختصاص می دهیم.

ما یک رابط ایجاد می کنیم که در آن انواع را برای ButtonProps خود تعریف می کنیم و سپس این رابط را در جزء خود می خوانیم:

 interface ButtonProps { count: number; onClick: () => void; } export default function Button({ count, onClick }: ButtonProps) { return ( <button onClick={onClick} className="bg-blue-500 hover:bg-blue-700 rounded text-white font-bold px-4 py-2" > I have been clicked {count} times </button> ); }
components/button.tsx

خطاها از بین رفته اند و شما آن را دارید: یک مقدمه کوچک برای TypeScript!

در اینجا بیایید یک commit دیگر با پیامی مانند buttons with shared state ایجاد کنیم.

فصل 4: چگونه هر دو جفت دکمه را به سایت خود اضافه کنیم

بیایید هر دو دکمه خود را با حالت مشترک و مستقل به نمایش بگذاریم و برنامه را اجرا کنیم.

بیایید button.tsx خود را به button-shared-state.tsx تغییر دهیم. اجازه دهید نام تابع، رابط، واردات در app/page.tsx و همچنین جزء در app/page.tsx را نیز تغییر دهیم. و اجازه دهید اینها را با استفاده از یک عبارت تابع با استفاده از const به جای اعلان تابع به صادرات نامگذاری شده تغییر دهیم:

 interface ButtonSharedStateProps { count: number; onClick: () => void; } export const ButtonSharedState = ({ count, onClick, }: ButtonSharedStateProps) => { return ( <button onClick={onClick} className="bg-blue-500 hover:bg-blue-700 rounded text-white font-bold px-4 py-2" > I have been clicked {count} times </button> ); };
components/button-shared-state.tsx
 "use client"; import { useState } from "react"; import { ButtonSharedState } from "@/components/button-shared-state"; export default function Home() { const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); } return ( <main className="flex min-h-screen flex-col items-center p-24 gap-4"> <h1>React Counter Button</h1> <ButtonSharedState count={count} onClick={handleClick} /> <ButtonSharedState count={count} onClick={handleClick} /> </main> ); }
app/page.tsx

حالا بیایید یک فایل components/button-independent-state.tsx ایجاد کنیم:

 "use client"; import { useState } from "react"; export const ButtonIndependentState = () => { const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); } return ( <button className="bg-blue-500 hover:bg-blue-700 rounded text-white font-bold py-2 px-4" onClick={handleClick} > I have been clicked {count} times </button> ); };
components/button-independent-state.tsx

کاری که ما در اینجا انجام دادیم مشابه منطق ما در ابتدای این راهنما است: ما وضعیت را در خود مؤلفه دکمه قرار داده ایم، به طوری که هر پیاده سازی مولفه دکمه حالت مستقل خود را ایجاد و ردیابی می کند.

بیایید ButtonIndependentState به app/page.tsx وارد کنیم:

 "use client"; import { useState } from "react"; import { ButtonSharedState } from "@/components/button-shared-state"; import { ButtonIndependentState } from "@/components/button-independent-state"; export default function Home() { const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); } return ( <main className="flex min-h-screen flex-col items-center p-24 gap-4"> <h1 className="text-3xl font-bold">React Counter Buttons</h1> <h2 className="text-xl">Buttons with shared state</h2> <ButtonSharedState count={count} onClick={handleClick} /> <ButtonSharedState count={count} onClick={handleClick} /> <h2 className="text-xl">Buttons with independent state</h2> <ButtonIndependentState /> <ButtonIndependentState /> </main> ); }
app/page.tsx

اکنون مجموعه‌ای از دکمه‌ها را به نمایش گذاشته‌ایم که حالت مستقل دارند و همچنین دکمه‌هایی که حالت مشترک دارند. ما کمی CSS اضافه کردیم تا همه چیز زیباتر به نظر برسد.

Screen-Recording-2024-06-21-at-12.25.22-PM
پروژه تمام شده ما

در اینجا اجازه دهید یک commit دیگر با پیامی مانند buttons with both shared and independent state اضافه کنیم.

فصل 5: نحوه استقرار سایت در Netlify

در GitHub منتشر کنید

بیایید برنامه خود را در جهان به نمایش بگذاریم تا آن را به نمایش بگذاریم. ما قصد داریم کد خود را به GitHub فشار دهیم و سپس آن را در Netlify مستقر کنیم.

اولین قدم این است که کد ما را به GitHub فشار دهید. اگر حساب GitHub ندارید، ابتدا یک حساب کاربری ایجاد کنید. در کد ویژوال استودیو، می‌توانید از پالت فرمان به GitHub فشار دهید: با فشار دادن ⇧⌘P پالت فرمان را باز کنید، سپس publish to GitHub را تایپ کنید و publish to public GitHub repository را انتخاب کنید.

حساب GitHub خود را باز کنید و تحلیل کنید که پروژه با موفقیت آپلود شده است.

در Netlify مستقر شوید

هنگامی که پروژه خود را در GitHub آپلود کردید، اکنون می توانید آن را در Netlify مستقر کنید. وب سایت Netlify را باز کنید و وارد شوید (یا اگر ندارید یک حساب بسازید).

روی add new site کلیک کنید و سپس import an existing project . هنگامی که از شما پرسیده شد Let's deploy your project with… ، GitHub را انتخاب کنید.

نام مخزن خود را از فهرست انتخاب کنید، سپس به سایت یک نام زیر site name بدهید. می‌توانید بقیه تنظیمات را در حالت پیش‌فرض رها کنید و سپس روی deploy [your site name] کلیک کنید.

اگر پروژه با موفقیت ساخته شود، شما یک لینک زنده از کار خود خواهید داشت!

نتیجه گیری و گام های بعدی

در این پروژه مفاهیم اساسی در React مانند ایجاد کامپوننت عملکردی، وارد کردن و صادرات ماژول ها، درونیابی جاوا اسکریپت در JSX با استفاده از بریس های فرفری، کار با حالت و استفاده از قلاب های React را آموخته اید.

همچنین مقدمه ای برای استفاده از تکنیک های CSS مبتنی بر ابزار با Tailwind CSS دیده اید، و مقدمه کوچکی برای گفت ن انواع به جاوا اسکریپت خود با TypeScript داشته اید. در نهایت، یاد گرفتید که چگونه پروژه خود را از طریق GitHub در Netlify مستقر کنید.

از اینجا کجا می توانید بروید؟ یک ایده برای گسترش پروژه می تواند ایجاد یک "تیک" باشد: شمارنده ای که می تواند افزایش یا کاهش یابد (شما یک دکمه دارید که تعداد شمارنده را افزایش می دهد و یکی که آن را کاهش می دهد).

به نام یادگیری، یکی از روش‌های موثر برای تثبیت مفاهیمی که در اینجا آموخته‌اید این است که یک پروژه را کاملاً تازه شروع کنید و ببینید آیا می‌توانید همه چیز را در این آموزش بدون تحلیل آموزش بسازید یا خیر. همانطور که باید تحلیل کنید، متوجه خواهید شد که کدام مفاهیم از مطالعه و تمرین بیشتر سود می برند.

اگر می‌خواهید در تماس باشید، می‌توانید:

من را در توییتر دنبال کنید

من را در لینکدین دنبال کنید

لطفاً در مورد آنچه ساخته اید همراه با هرگونه سؤال یا بازخوردی که ممکن است داشته باشید، پست کنید.

کد نویسی مبارک!

خبرکاو

ارسال نظر

دیدگاه‌ها بسته شده‌اند.


تبليغات ايهنا تبليغات ايهنا

تمامی حقوق مادی و معنوی این سایت متعلق به خبرکاو است و استفاده از مطالب با ذکر منبع بلامانع است