تشریح رابط کاربری

mohsen1 ماه قبل
ارسال شده در
react/docs/v19

کار اصلی کتابخانه React رندر کردن رابط‌های کاربری (UI) است. UI از واحدهای کوچک مانند دکمه‌ها، متن و تصاویر ساخته شده است. React به شما این امکان را می‌دهد که آن‌ها را به کامپوننت های قابل استفاده مجدد و تو در تو تبدیل کنید. از وب‌سایت‌ها تا برنامه‌های تلفن همراه، هر چیزی که روی صفحه نمایش است می‌تواند به کامپوننت تقسیم شود. در این فصل، خواهید آموخت که چگونه کامپوننت React بسازید، شخصی‌سازی کنید و به صورت شرطی نمایش دهید.

اولین کامپوننت شما

برنامه‌های React از بخش‌های ایزوله شده UI به نام کامپوننت ساخته شده‌اند. یک کامپوننت React تابعی جاوا اسکریپت است که می‌توانید آن را سینتکس JSX پر کنید. کامپوننت ها می‌توانند به کوچکی یک دکمه یا به بزرگی یک صفحه کامل باشند. در زیر یک کامپوننت Gallery آمده که سه کامپوننت Profile را رندر می‌کند:

      function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3As.jpg"
      alt="Katherine Johnson"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}
    

مشاهده اجرای کد در CodeSandBox

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

ایمپورت و اکسپورت کردن کامپوننت ها

همه کامپوننت ها را می توانید در یک فایل تعریف کنید، اما فایل‌های بزرگ برای توسعه و نگهداری سخت هستند. برای حل این موضوع، می‌توانید یک کامپوننت را در فایل خود قرار دهید و سپس آن را در فایل دیگری برای استفاده ایمپورت کنید:

      import Gallery from './Gallery.js';

export default function App() {
  return (
    <Gallery />
  );
}
    
      import Profile from './Profile.js';

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}
    
      export default function Profile() {
  return (
    <img
      src="https://i.imgur.com/QIrZWGIs.jpg"
      alt="Alan L. Hart"
    />
  );
}
    

مشاهده کد در CodeSandBox

مقاله ایمپورت و اکسپورت کردن کامپوننت ها را برای یادگیری تقسیم کامپوننت ها مطالعه کنید.

نوشتن مارکاپ با JSX

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

اگر ما نشانه‌گذاری HTML موجود را به یک کامپوننت React اضافه کنیم، ممکن است همیشه کار نکند:

      export default function TodoList() {
  return (
    // This doesn't quite work!
    <h1>Hedy Lamarr's Todos</h1>
    <img
      src="https://i.imgur.com/yXOvdOSs.jpg"
      alt="Hedy Lamarr"
      class="photo"
    >
    <ul>
      <li>Invent new traffic lights
      <li>Rehearse a movie scene
      <li>Improve spectrum technology
    </ul>
  );
}
    

و خطایی مانند خطای زیر را دریافت کنید:

      Error
/src/App.js: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>? (5:4)

  3 |     // This doesn't quite work!
  4 |     <h1>Hedy Lamarr's Todos</h1>
> 5 |     <img
    |     ^
  6 |       src="https://i.imgur.com/yXOvdOSs.jpg"
  7 |       alt="Hedy Lamarr"
  8 |       class="photo"
    

اگر شما HTML موجودی مانند کد بالا دارید، می‌توانید آن را با استفاده از یک مبدل اصلاح کنید و بعد به کامپوننت خود اضافه کنید:

      export default function TodoList() {
  return (
    <>
      <h1>Hedy Lamarr's Todos</h1>
      <img
        src="https://i.imgur.com/yXOvdOSs.jpg"
        alt="Hedy Lamarr"
        className="photo"
      />
      <ul>
        <li>Invent new traffic lights</li>
        <li>Rehearse a movie scene</li>
        <li>Improve spectrum technology</li>
      </ul>
    </>
  );
}
    

مشاهده نتیجه در CodeSandBox

مقاله نوشتن نشانه‌گذاری با JSX را بخوانید تا نحوه استفاده صحیح از JSX یادبگیرید.

جاوا اسکریپت در JSX با آکولادها

نحو JSX به شما امکان استفاده از مارکاپ شبیه HTML درون فایل جاوا اسکریپت را می دهد و منطق رندر و محتوا را در یک مکان جمع می کند. گاهی اوقات می خواهیم کمی منطق جاوا اسکریپت برای دینامیک کردن نمایش در بین المان ها اضافه کنید. در این وضعیت، می‌توانید از آکولادها در JSX برای "باز کردن یک پنجره" به جاوا اسکریپت استفاده کنید:

      const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src="https://i.imgur.com/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}
    

مشاهده نتیجه اجرای کد بالا در CodeSandBox

مقاله جاوا اسکریپت در JSX با آکولادها را بخوانید نحوه تزریق داده‌های جاوا اسکریپت به JSX را یادبگیرید.

ارسال props به یک کامپوننت

کامپوننت های React از props برای ارتباط با یکدیگر استفاده می‌کنند. هر کامپوننت والد می‌تواند اطلاعات را به کامپوننت‌های فرزند خود با پاس دادن props انتقال دهد. Props ممکن است شما را به یاد ویژگی‌های HTML بیندازد، با این تفاوت که با Props می‌توانید هر مقدار جاوا اسکریپتی را از طریق آن‌ها به کامپوننت منتقل کنید، از جمله اشیا، آرایه‌ها، توابع و حتی JSX!

مشاهده خروجی کد زیر در CodeSandBox

      import { getImageUrl } from './utils.js'

export default function Profile() {
  return (
    <Card>
      <Avatar
        size={100}
        person={{
          name: 'Katsuko Saruhashi',
          imageId: 'YfeOqp2'
        }}
      />
    </Card>
  );
}

function Avatar({ person, size }) {
  return (
    <img
      className="avatar"
      src={getImageUrl(person)}
      alt={person.name}
      width={size}
      height={size}
    />
  );
}

function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}

    
      export function getImageUrl(person, size = 's') {
  return (
    'https://i.imgur.com/' +
    person.imageId +
    size +
    '.jpg'
  );
}
    
      .card {
  width: fit-content;
  margin: 5px;
  padding: 5px;
  font-size: 20px;
  text-align: center;
  border: 1px solid #aaa;
  border-radius: 20px;
  background: #fff;
}
.avatar {
  margin: 20px;
  border-radius: 50%;
}
    

برای آگاهی بیشتر نسبت به عملکر ویژگی های، مطلب ارسال Props به یک کامپوننت را مطالعه کنید.

رندر کردن شرطی

کامپوننت ها گاهی بسته به شرابط مختلف نیاز به نمایش چیزهای متفاوتی دارند. برای مثال فرض کنید می خواهیم پیامی به کاربر نمایش دهیم، اگر پیام خطا بود باید با رنگ قرمز و اگر پیام موفقت بود باید با رنگ سبز نمایش دهیم. در React، می‌توانید JSX را به صورت شرطی و با استفاده از سینتکس جاوا اسکریپت مانند دستورهای if، اپراتورهای && و ? : رندر کنید.

در این مثال، اپراتور جاوا اسکریپت && برای رندر کردن شرطی برای نمایش علامت تیک استفاده شده است:

مشاهده نتیجه کد زیر در CodeSandBox

      function Item({ name, isPacked }) {
  return (
    <li className="item">
      {name} {isPacked && '✅'}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item
          isPacked={true}
          name="Space suit"
        />
        <Item
          isPacked={true}
          name="Helmet with a golden leaf"
        />
        <Item
          isPacked={false}
          name="Photo of Tam"
        />
      </ul>
    </section>
  );
}
    

برای آشنایی بیشتر با رندر شرطی، لطفا مطلب رندر کردن شرطی را مطالعه کنید.

رندر کردن لیست‌ها

حتمن در زمان توسعه یک اپ برایتان پیش آمده که بخواهید یک لیستی از داده ها را در غالب چندین کامپوننت به کاربر نمایش دهید. برای این کار می‌توانید از ادغام filter() و map() جاوا اسکریپت با JSX برای فیلتر و تبدیل آرایه‌ی داده‌های خود به آرایه‌ای از کامپوننت‌ها استفاده کنید.

برای هر آیتم آرایه، باید یک key منحصر به فرد مشخص کنید. معمولاً شناسه (ID) از پایگاه داده دریافت شده و به عنوان key استفاده میشود. کلیدها به React اجازه می‌دهند که محل هر آیتم را در لیست را دنبال کند حتی با وجود تغییر لیست.

نتیجه کد مربوط به رندر کردن لیست ها را در CodeSandBox ببینید

      import { people } from './data.js';
import { getImageUrl } from './utils.js';

export default function List() {
  const listItems = people.map(person =>
    <li key={person.id}>
      <img
        src={getImageUrl(person)}
        alt={person.name}
      />
      <p>
        <b>{person.name}:</b>
        {' ' + person.profession + ' '}
        known for {person.accomplishment}
      </p>
    </li>
  );
  return (
    <article>
      <h1>Scientists</h1>
      <ul>{listItems}</ul>
    </article>
  );
}
    
      export const people = [{
  id: 0,
  name: 'Creola Katherine Johnson',
  profession: 'mathematician',
  accomplishment: 'spaceflight calculations',
  imageId: 'MK3eW3A'
}, {
  id: 1,
  name: 'Mario José Molina-Pasquel Henríquez',
  profession: 'chemist',
  accomplishment: 'discovery of Arctic ozone hole',
  imageId: 'mynHUSa'
}, {
  id: 2,
  name: 'Mohammad Abdus Salam',
  profession: 'physicist',
  accomplishment: 'electromagnetism theory',
  imageId: 'bE7W1ji'
}, {
  id: 3,
  name: 'Percy Lavon Julian',
  profession: 'chemist',
  accomplishment: 'pioneering cortisone drugs, steroids and birth control pills',
  imageId: 'IOjWm71'
}, {
  id: 4,
  name: 'Subrahmanyan Chandrasekhar',
  profession: 'astrophysicist',
  accomplishment: 'white dwarf star mass calculations',
  imageId: 'lrWQx8l'
}];
    
      export function getImageUrl(person) {
  return (
    'https://i.imgur.com/' +
    person.imageId +
    's.jpg'
  );
}
    

مقاله رندر کردن لیست‌ها را بخوانید تا یاد بگیرید چگونه یک لیست از کامپوننت‌ها را رندر کنید و چگونه یک کلید را انتخاب کنید.

خالص نگهداشتن کامپوننت ها

به توابعی در جاوا اسکریپت خالص می گوییم که:

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

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

      let guest = 0;

function Cup() {
  // Bad: تغییر متغیر موجود خارج از تابع
  guest = guest + 1;
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup />
      <Cup />
      <Cup />
    </>
  );
}
    

شما می‌توانید این کامپوننت را با ارسال یک prop به جای تغییر متغیر موجود، خالص کنید:

      function Cup({ guest }) {
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup guest={1} />
      <Cup guest={2} />
      <Cup guest={3} />
    </>
  );
}
    

برای یادگیری بیشتر در رابطه با این موضوع، مطلب حفظ اجزاء به صورت خالص مطالعه نمایید.

به UI به چشم یک درخت نگاه کنید

فریم ورک React از ساختار داده درختی برای مدل‌سازی روابط بین کامپوننت ها و ماژول‌ها استفاده می‌کند.

یک درخت رندر React نمایانگر رابطه والد و فرزندی بین کامپوننت ها است.

مثالی از درخت رندر React

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

مدل‌سازی رابطه بین ماژول‌های جاوا اسکریپت راه خوبی برای درک برنامه است که ما به آن درخت وابستگی ماژول‌ها می‌گوییم.

مثالی از درخت وابستگی ماژول ها

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

برای آشنایی بیشتر با نحوه درخت رندر و درخت وابستگی، مطلب UI به عنوان یک درخت را مطالعه نمایید.

قدم بعدی چیست؟

به مطلب اولین کامپوننت شما رفته و همه سرفصل های بالا را یک به یک مطالعه نمایید !

یا اگر با این موضوعات آشنا هستید، به سراغی مطالعه مطلب اضافه کردن تعامل به برنامه بروید.

رای
0
ارسال نظر
مرتب سازی:
اولین نفری باشید که نظر می دهید!