ساخت کامپوننت Layout و طرح اولیه

Building Layout component and Initial Design

16 آبان 1398
ساخت کامپوننت Layout و طرح اولیه

در این قسمت از دوره جامع آموزش react باید درخت کامپوننت هایمان را بررسی و قسمتی را کدنویسی کنیم:

خلاصه ای از نقشه ی ما (ساختار کامپوننت ها) در پروژه ی همبرگر ساز [سایز تصویر بزرگ است، برای مشاهده ی کامل زوم کنید]

ما می توانیم کدنویسی پروژه را به دو قسمت اصلی تقسیم کنیم:

  • صفحه همبرگر ساز
  • منوی navigation و...

از صفحه همبرگر ساز شروع می کنیم. همانطور که در تصویر بالا می بینید تمام کامپوننت ها درون یک کامپوننت اصلی به نام layout قرار دارند. بنابراین باید قبل از هر کاری آن را ایجاد کنیم (البته شما میتوانید همان App.js را به layout تبدیل کنید اما من یک کامپوننت کاملا جدا می سازم). در پوشه src دو پوشه دیگر به نام های components و containers ایجاد کنید. یادتان باشد که container ها کامپوننت های stateful (دارای state) هستند و کامپوننت های stateless (بدون state) را نیز درون components قرار می دهیم (حتی کامپوننت های کلاس-محوری که بدون state باشند در این قسمت قرار می گیرند). بنابراین درون پوشه components یک پوشه دیگر به نام Layout و درون آن فایل Layout.js را ایجاد می کنم. پوشه دیگری را نیز باید درون src ایجاد کنیم؛ پوشه assets که مسئول نگهداری لوگو و... است.

وارد layout شوید تا کامپوننت کاربردی خود را بنویسیم. sudo code این قسمت از پروژه ما به شکل زیر است:

import React from 'react';

const layout = (props) => (
    <div>Toolbar, Side drawer, Backdrop</div>
    <main>
        {props.children}
    </main>
);

این کد اصلی نیست بلکه sudo code است یعنی کلیت کار را به صورت ساده نوشته ام (واضح است که بعدا به جای نوشتن کلمه Toolbar واقعا باید کدهای آن را بنویسیم). نوار ابزار و منوی کشویی و backdrop را درون یک div و قسمت اصلی صفحه را هم در تگ main قرار خواهیم داد.

از آنجایی که کدهای کنار هم را داریم (رابطه خواهر و برادری تگ های div و main) با خطا روبرو می شویم. همانطور که گفتیم برای حل این مشکل یا باید یک عنصر ریشه ای داشته باشیم (مثلا همه چیز را درون یک div قرار دهیم) یا باید از HOC ها استفاده کنیم و یا اینکه تگ ها را به صورت یک آرایه به همراه key نمایش دهیم. من نیازی به عنصر ریشه ای ندارم، همچنین چاپ دو عنصر به صورت آرایه اضافه کاری است، بنابراین یک پوشه به نام hoc درون پوشه src ایجاد کرده و درون آن فایل Auxx.js را می نویسم:

const aux = (props) => props.children;

export default aux;

هشدار: شما نباید در ویندوز فایلی با نام Aux داشته باشید (از نام های رزرو شده در ویندوز است) به همین خاطر ما فایل خود را با نام Auxx نوشته ایم (یک x اضافی). اگر چنین فایلی ایجاد کنید، حذف آن بعدها دردسرهای فراوانی خواهد داشت.

همانطور که می بینید این فایل بسیار ساده است و فقط عناصر درون خود را نمایش می دهد. همچنین از آنجایی که هیچ کد JSX ای نداریم حتی نیازی به import کردن کتابخانه react نیز نیست. حالا به فایل Layout.js برگشته و آن را import می کنیم:

import Aux from '../../hoc/Auxx';

و سپس Aux را به عنوان عنصر ریشه ای در نظر می گیریم تا خطا برطرف شود:

import React from 'react';
import Aux from '../../hoc/Auxx';

const layout = (props) => (
    <Aux>
        <div>Toolbar, Side drawer, Backdrop</div>
        <main>
            {props.children}
        </main>
    </Aux>
);

export default layout;

حالا وارد فایل App.js می شویم تا در آن از کامپوننت Layout استفاده کنیم:

import Layout from './components/Layout/Layout';

class App extends Component {
  render() {
    return (
      <div>
        <Layout>
          <p>Test</p>
        </Layout>
      </div>
    );  
  }
}

توجه داشته باشید که عنصر Layout را به شکل self-closing (بدون تگ پایانی) ننویسید:

<Layout />

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

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

خروجی کامپوننت Layout
خروجی کامپوننت Layout

اما یک مشکل وجود دارد؛ فونت open sans روی پروژه ما اعمال نشده است. آیا می دانید چرا؟ به دلیل اینکه هنوز از آن استفاده نکرده ایم! از آنجایی که این فونت را برای تمام پروژه می خواهیم، باید آن را در فایل CSS سراسری خود (index.css) اضافه کنیم:

  font-family: "Open Sans", sans-serif;

در این حالت Open Sans فونت اصلی پروژه ما است و در صورتی که این فونت به مشکل بخورد، سیستم فونت sans-serif را برای ما اعمال خواهد کرد. حالا که فونت ها نیز تنظیم شده اند نوبت به ساخت کامپوننت همبرگرساز است.

درون پوشه containers یک پوشه به نام BurgerBuilder ساخته و فایلی به همین نام با پسوند js در آن ایجاد کنید (این کامپوننت دارای state خواهد بود به همین دلیل آن را درون container قرار می دهیم). محتویات کلی این کامپوننت به شکل زیر خواهد بود:

import React, {Component} from 'react';

class BurgerBuilder extends Component {
    render() {
        return ();
    }
}

همانطور که گفتیم برای کامپوننت های دارای state از کامپوننت های کلاس-محور استفاده می کنیم تا بعدا که به React hook برسیم و کل پروژه را با استفاده از React hooks بازنویسی کنیم. حالا سوالی پیش می آید: چه چیزی را باید در این قسمت نمایش دهیم؟ این پروژه بعدا بزرگتر خواهد شد اما فعلا دو چیز باید نمایش داده شود:

  • شکل گرافیکی همبرگر
  • کنترل های خرید
import React, { Component } from 'react';

import Aux from '../../hoc/Auxx';

class BurgerBuilder extends Component {
    render() {
        return (
            <Aux>
                <div>Burger</div>
                <div>Build Controls</div>
            </Aux>
        );
    }
}

export default BurgerBuilder;

از آنجایی که نمی خواستم div ریشه ای داشته باشم از همان عنصر Aux خودمان استفاده کرده ام تا به خطا برخورد نکنیم. حالا به فایل App.js میرویم و پاراگراف test را حذف می کنیم تا از BurgerBuilder به جای آن استفاده کنیم. قسمت اضافه شده به فایل App.js بدین شکل می باشد:

import BurgerBuilder from './containers/BurgerBuilder/BurgerBuilder';

class App extends Component {
  render() {
    return (
      <div>
        <Layout>
          <BurgerBuilder />
        </Layout>
      </div>
    );
  }
}

از آنجایی که نمی خواهیم عناصری را در این قسمت درون BurgerBuilder قرار دهیم، از تگ های self-closing (بدون تگ پایانی) استفاده کرده ایم. در مرورگر باید چنین چیزی را مشاهده کنید:

خروجی کامپوننت BuildBurger
خروجی کامپوننت BuildBurger

با اینکه هنوز کدهای خودمان را ننوشته ایم اما از آنجایی که می خواهیم بین همبرگرساز و toolbar و ... فاصله باشد باید کدهای CSS آن را بنویسیم. درون پوشه Layout یک فایل به نام Layout.module.css ایجاد کنید (برای استفاده از CSS Module باید پسوند فایل حتما دارای module.css. باشد) و یک کلاس با نام دلخواه به شکل زیر بنویسید:

.Content {
    margin-top: 16px;
}

حالا به فایل Layout.js می رویم و از آن استفاده می کنیم:

import classes from './Layout.module.css';

const layout = (props) => (
    <Aux>
        <div>Toolbar, Side drawer, Backdrop</div>
        <main className={classes.Content}>
            {props.children}
        </main>
    </Aux>
);

همانطور که می دانید، نام classes سلیقه ای است و شما می توانید هر نام دیگری (مانند Styles و ...) به آن بدهید.

اگر فایل را ذخیره کنید باید در مرورگر شاهد اضافه شدن این فاصله باشید:

خروجی پس از اضافه کردن margin-top
خروجی پس از اضافه کردن margin-top

در قسمت بعد به سراغ کدنویسی همبرگر خواهیم رفت.

دانلود کدهای این جلسه

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

دیدگاه‌های شما

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