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

17 اسفند 1397
درسنامه درس 4 از سری آموزش react (ری اکت)
React-nested-components

در جلسه قبل، اولین کامپوننت مان را ایجاد کردیم. در این قسمت کار با کامپوننت app را ادامه داده و شروع به ساخت یک رابط کاربری پیچیده برای آن می کنیم. یکی از عنصرهای رایج وب، timeline است. برای مثال ممکن است برنامه ای داشته باشیم که بخواهیم تاریخچه رویدادهایی که اتفاق می افتد را نمایش دهد، مثل فیسبوک و توییتر.

استایل ها

چون هدف مان در مقاله، آموزش css نیست، بنابراین استایل های cssیی که در این برنامه استفاده شده را آموزش نخواهیم داد. با این حال می خواهیم مطمئن  شویم که ظاهر timeline شما مشابه timeline ما است. اگر فایل css زیر را توسط تگ <link/> به برنامه اضافه کنید، ظاهر timeline شما مشابه ما خواهد شد.

<link
   href="https://gist.githubusercontent.com/auser/2bc34b9abf07f34
         f602dccd6ca855df1/raw/070d6cd5b4d4ec1a3e6892d43e877039a91a9108
         /timeline.css" rel="stylesheet" type="text/css" />

کدهایcss این پروژه را می توانید از آدرس زیر دریافت کنید.

 https://gist.github.com/auser/2bc34b9abf07f34f602dccd6ca855df1

به علاوه اگر می خواهید timeline شما دقیقا مشابه ما شود، باید font-awesome را هم به برنامه تان اضافه کنید. در واقع پکیج FontAwesome به شما این قابلیت را می دهد که از آیکون های متنوع بهره برده و نرم افزار را زیبا تر کنید.

چندین روش برای انجام اینکار وجود دارد. ساده ترین راه، وارد کردن کد زیر به برنامه است.

<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" type="text/css" />

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

class Timeline extends React.Component {
  render() {
    return (
      <div className="notificationsFrame">
        <div className="panel">
          <div className="header">

            <div className="menuIcon">
              <div className="dashTop"></div>
              <div className="dashBottom"></div>
              <div className="circle"></div>
            </div>

            <span className="title">Timeline</span>

            <input
              type="text"
              className="searchInput"
              placeholder="Search ..." />

            <div className="fa fa-search searchIcon"></div>
          </div>
          <div className="content">
            <div className="line"></div>
            <div className="item">

              <div className="avatar">
                <img
                alt='doug'
                src="http://www.croop.cl/UI/twitter/images/doug.jpg" />
              </div>

              <span className="time">
                An hour ago
              </span>
              <p>Ate lunch</p>
            </div>

            <div className="item">
              <div className="avatar">
                <img
                  alt='doug' src="http://www.croop.cl/UI/twitter/images/doug.jpg" />
              </div>

              <span className="time">10 am</span>
              <p>Read Day two article</p>
            </div>

            <div className="item">
              <div className="avatar">
                <img
                  alt='doug' src="http://www.croop.cl/UI/twitter/images/doug.jpg" />
              </div>

              <span className="time">10 am</span>
              <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
            </div>

            <div className="item">
              <div className="avatar">
                <img
                  alt='doug' src="http://www.croop.cl/UI/twitter/images/doug.jpg" />
              </div>

              <span className="time">2:21 pm</span>
              <p>Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>
            </div>

          </div>
        </div>
      </div>
    )
  }
}

در صورتیکه تمام مراحل بالا را به درستی طی کرده باشید باید خروجی شما به صورت زیر باشد:

کامپوننت timeline
کامپوننت timeline در React

تقسیم کردن برنامه به بخش های کوچکتر

به جای اینکه کل یک برنامه را در یک کامپوننت ایجاد کنیم، میخواهیم برنامه را به چند کامپوننت مختلف تقسیم کنیم.

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

  1. نوار عنوان (title bar)
  2. محتوا

کامپوننت timeline

همچنین می توانیم بخش محتوای کامپوننت را به چند بخش مجزا تقسیم کنیم.

کامپوننت timeline

اگر بخواهیم یک مرحله جلوتر برویم، می توانیم حتی خود نوار عنوان را هم به سه کامپوننت مختلف مثل دکمه menu، عنوان و آیکن search تقسیم کنیم.

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

در هر حال، معمولا بهتر است که توسعه برنامه را با کامپوننت ها شروع کنید.

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

کامپوننت Container

برای ساخت برنامه نوتیفیکیشن، ابتدا یک container برای نگهداری برنامه ایجاد کنید.

این container مانند یک ظرف برای دو کامپوننت دیگر عمل می کند.

هیچ کدام از این کامپوننت ها به قابلیت خاصی نیاز ندارند، بنابراین آنها مشابه کامپوننت HelloWorld تنها یک تابع render دارند. حال برای ساخت یک کامپوننت wrapper (نگهدارنده) باید App را مطابق زیر فراخوانی کنیم.

class App extends React.Component {
  render() {
    return (
      <div className="notificationsFrame">
        <div className="panel">
          {/* content goes here */}
        </div>
      </div>
    )
  }
}

دقت کنید که در ری اکت به جای خصیصه class که در html استفاده می کردیم، از className باید استفاده کنیم.

همچنین به یاد داشته باشید که ما بطور مستقیم با DOM کار نخواهیم کرد، بلکه از jsx (که همان جاوا اسکریپت است) استفاده می کنیم.

دلیل اینکه ما از className به جای class استفاده می کنیم این است که واژه class یک کلمه رزرو شده دز جاوا اسکریپت است. اگر از class استفاده کنیم، یک پیام خطا در کنسول دریافت خواهیم کرد.

کامپوننت های فرزند

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

 

توسط کامپوننت wrapperیی که تعریف کردیم می توانیم کامپوننت های title و content مان را ایجاد کنیم و همچنین سورس هر کدام از آنها را از کد برنامه اصلی آن بر می داریم و در داخل هر کدام از آنها قرار می دهیم.

برای نمونه کامپوننت header شامل یک عنصر کانتینر <div className=”header”>، آیکن منو، یک عنوان و یک نوار جستجو است.

class Header extends React.Component {
  render() {
    return (
      <div className="header">
        <div className="fa fa-more"></div>

        <span className="title">Timeline</span>

        <input
          type="text"
          className="searchInput"
          placeholder="Search ..." />

        <div className="fa fa-search searchIcon"></div>
      </div>
    )
  }
}

با توضیحات فوق، کامپوننت هدر سایت ما به صورت زیر خواهد بود:

کامپوننت header

و در نهایت، کامپوننت content که شامل timelineهای مختلف است را می نویسیم.

هر آیتم این timeline در یک کامپوننت مجزا ایجاد می شود، و به هر کدام از آنها یک آواتار، timestamp و مقداری متن نسبت داده می شود.

class Content extends React.Component {
  render() {
    return (
      <div className="content">
        <div className="line"></div>

        {/* Timeline item */}
        <div className="item">
          <div className="avatar">
            <img
            alt='Doug'
            src="http://www.croop.cl/UI/twitter/images/doug.jpg" />
            Doug
          </div>

          <span className="time">
            An hour ago
          </span>
          <p>Ate lunch</p>
          <div className="commentCount">
            2
          </div>
        </div>

        {/* ... */}

      </div>
    )
  }
}

کامنت گذاری در ری اکت (React)

برای نوشتن کامنت برای یک کامپوننت در ری اکت از براکت استفاده می شود (منظور از کامنت همان توضیحات کدها می باشد).

بر خلاف کامنت html که مانند زیر انجام می شود

<!-- this is a comment in HTML -->

برای نوشتن یک کامنت در ری اکت باید مطابق زیر عمل شود.

{/* This is a comment in React */}

قرار دادن کامپوننت ها در کنار هم

حال که ما دو کامپوننت فرزند داریم باید کامپوننت های content و Header را هم به عنوان فرزند کامپوننت های App تنظیم کنیم.

کامپوننت App می تواند از این کامپوننت ها همانند دیگر عناصر پیش فرض html استفاده کند. این کامپوننت App شامل یک هدر و محتوا است.

class App extends React.Component {
  render() {
    return (
      <div className="notificationsFrame">
        <div className="panel">
          <Header />
          <Content />
        </div>
      </div>
    )
  }
}

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

با این حال این برنامه هیچ تعاملی با کاربر برقرار نمی کند و همچنین شامل داده ای سفارشی هم نمی شود.

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

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش react (ری اکت) توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما (2 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

فاطمه
04 مهر 1398
سلام مرسی از مطالب خوبتون ببخشید من وقتی کلا تابع render رو مینویسم و تگ های jsx رو return میکنم برنامه ام اجرا نمیشه و ارور زیر رو میده . در صورتی که هم react ,reactDOM,babel همه لود هستند . شما میدونید مشکلش چیه ؟ Uncaught SyntaxError: Unexpected token '<'

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

sobhan
03 مهر 1398
سلام من چند کلن انگلیسی مطالعه میکنم ولی چنتا سایت ایرانی هستن واقعن ارزش مطالعه داره شما اصولو ب خوبی بیان میکنید و این خیلی مهمه مرسی بابات سایتتون

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.