حمیدرضا ناطقی
حمیدرضا ناطقی
خواندن ۴ دقیقه·۴ سال پیش

ایزوله کردن استایل در React به کمک CSS Modules

استایل کامپوننت یا در یک فایل جداگونه با پسوند css یا scss و یا مستقیما در فایل جاوا اسکریپت به کمک مفهومی به نام css-in-js تعریف میشه.

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

فایل جداگونه یا css-in-js؟

وقتی از فایل جداگونه استفاده میکنی، معمولا، یک فایل با پسوند css یا scss و همنام با کامپوننت میسازی و به فایل جاوا اسکریپت کامپوننت وارد میکنی، تا بخشی از پکیج باشه. متناوبا، میتونی از یک کتابخونه استفاده کنی که از قواعد css-in-js پیروی میکنه و به کمک آبجکت های json استایل هارو مستقیما در فایل جاوا اسکریپت درج میکنه. مفهوم css-in-js یک کتابخونه نیست؛ گروهی از کتابخونه هاست که از قواعد مشابهی پیروی میکنن.

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

مفهوم css-in-js با تولید گزینشگرهای منحصربفرد از این تداخل جلوگیری میکنه.

ساخت کامپوننت باکس با استایل

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

دو باکس سبز رنگ بجای یک باکس قرمز و یک باکس سبز
دو باکس سبز رنگ بجای یک باکس قرمز و یک باکس سبز

این کدی هستش که برای این دو باکس نوشته شده.

فایل استایل GreenBox.css

.box { background: green; }

فایل جاوا اسکریپت GreenBox.jsx

import React from 'react'; import './GreenBox.css'; export function GreenBox() { return <div className='box'>Green Box</div>; }

فایل استایل RedBox.css

.box { background: red; }

فایل جاوا اسکریپت RedBox.jsx

import React from 'react'; import './RedBox.css'; export function RedBox() { return <div className='box'>Red Box</div>; }

مشکل کجاست؟

دو کامپوننت متفاوت تعریف کردیم؛ که هر کدوم استایل خودشو داره. هر دوی اینا کلاسی دارن به اسم box با رنگ پس زمینه متفاوت. وقتی این کد کامپایل میشه، ابزاری که فایل هارو کنار هم میچینه، تمام استایل هارو با هم گروه بندی میکنه، و در زمان اجرا، به head صفحه تزریق میکنه.

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

استایل محاسبه شده کلاس box
استایل محاسبه شده کلاس box

چگونه از رخداد این مشکل جلوگیری کنیم؟

متدولوژی های محبوبی، مثل BEM، ABEM، Atomic و SMACSS هستن که از تداخل این نامگذاری ها در مرورگر جلوگیری میکنن.

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

برای اتوماسیون این فرایند، از ماژولی به نام CSS Modules استفاده میکنیم، کتابخونه ای که اطمینان میده در زمان اجرا هر کامپوننت از کلاس های منحصربفردی استفاده کنه.

استایل بندی به کمک CSS Modules

برای استفاده از این ماژول، باید به نام فایل استایل کلمه module. رو قبل از پسوند فایل اضافه کنی.

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

فایل استایل GreenBox.module.css

.box { background: green; }

فایل جاوا اسکریپت GreenBox.jsx

import React from 'react'; import classes from './GreenBox.module.css'; export function GreenBox() { return <div className={classes.box}>Green Box</div>; }

فایل استایل RedBox.module.css

.box { background: red; }

فایل جاوا اسکریپت RedBox.jsx

import React from 'react'; import classes from './RedBox.module.css'; export function RedBox() { return <div className={classes.box}>Red Box</div>; }

مشکل حل شد

reactمبتدیمعماریcss
برنامه نویس
شاید از این پست‌ها خوشتان بیاید