مروری بر کتابخانه ReactJS - قسمت پنجم - Composability
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: سه دقیقه

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

کامپوننت مالک میتواند داده‌های ورودی را برای اجزای سازنده خود به صورت یک سویه (one-way data binding) فراهم کند.  گاهی داده‌های مورد نیاز فرزندان، به طور مستقیم به مالک و از مالک به طور غیر مستقیم به فرزندان ارسال میشود. اما ممکن است لازم باشد که داده‌ها در اثر محاسبه در کامپوننت مالک، ایجاد و نتیجه به فرزندان ارسال شود. به هر صورت باید دقت داشته باشیم که در هر دو حالت اگر منبع داده و یا محسابه تغییر کنند، در به روز رسانی‌ها، توسط React بازتاب آن را خواهیم داشت. در مثال زیر کامپوننت DisplayAllInfos تشکیل شده از چهار کامپوننت دیگر است.

class DisplayAllInfos extends React.Component{
    render(){
        return (
            <div classID="something" className="something">
                <ProfilePhoto src={} />
                <UserPersonalInfo userInfo={}/>
                <UserJobInfo jobInfo={}/>
                <UserContactInfo contactInfo={}/>
            </div>
        )
    }
}

حتی میشود تگ <div> در مثال بالا را بصورت یک کامپوننت درآورد و سایر کامپوننت‌ها را به عنوان فرزند به آن کامپوننت معرفی کرد. روش کار به صورت زیر است. 

class Container extends React.Component{
    render(){
        <div classID="something" className="something">
            {this.props.children}
        </div>
    }
}

class DisplayAllInfos extends React.Component{
    render(){
        return (
            <Container>
                <ProfilePhoto src={} />
                <UserPersonalInfo userInfo={}/>
                <UserJobInfo jobInfo={}/>
                <UserContactInfo contactInfo={}/>
            </Container>
        )
    }
}

توسط خاصیت this.proprs.children در کامپوننت Container فرزندانی که برای این کامپوننت در نظر گرفته شده را نمایش میدهیم و به آنها دسترسی داریم.

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

var hotDrinks = [
    {id: 1, item: "Tea", price: "7000" },
    {id: 2, item: "Espresso", price: "10000" },
    {id: 3,  item: "Hot Chocolate", price: "12000" }
];

// {this.state.menuList.map(item => <MenuItem {...item} />)}

var Menu = React.createClass({
    render: function () {
        return (
            <div className="row">
                <div className="col-md-4">
                    <ul className="list-group">
                        {this.state.menuList.map(item => <MenuItem key={item.id} {...item} />)}
                    </ul>
                </div>
            </div>
        )
    }
});

آن خط کدی که به صورت کامنت گذاشته شده همان روش قبل در مثال نوشیدنی‌هاست. در حالت اصلاح شده برای هر یک از MenuItem‌ها یک id در نظر گرفته شده. باید توجه داشته باشیم که کلید‌ها حتما یگانه باشند و نکته دیگر اینکه این کلیدها فقط در زمان معرفی کامپوننت استفاده میشوند و نمیتوانیم داخل خود کامپوننت آنها را داشته باشیم. برای مثال در یک کامپوننت MenuItem مقدار this.props.key قابل استفاده نیست. هیچگاه از اندیس خود اعضای آرایه به عنوان کلید استفاده نکنید، چرا که با حذف یک مورد، در عمل وضعیت کلیدها را بهم ریخته‌اید و شاهد رفتاری غیرقابل پیش‌بینی خواهید شد. 

در قسمت بعدی اعتبار‌سنجی را در کتابخانه React بررسی میکنیم.