اگر مدتی است که با React کار میکنید، احتمالاً با آن برخورد کردهاید ظرف و اجزای ارائه ، یا اجزای هوشمند و گنگ. این اصطلاحات الف را توصیف می کنند الگو که لایه UI اجزای React را از منطق جدا می کند.
جداسازی UI از منطق تجاری چیزی منحصر به فرد برای React نیست: جداسازی نگرانی ها یک اصل طراحی است که قبلاً در دهه 70 وجود داشته است. به عنوان مثال، جداسازی کدی که به پایگاه داده دسترسی دارد از منطق تجاری موجود در باطن، معمول است.
بنابراین در React، ما این مشکل را با ایجاد کامپوننتهای کانتینری که تمام منطق را در بر میگیرد، حل کردیم، که سپس دادهها را از طریق props به مؤلفه ارائه ارسال میکرد.
با معرفی قلابهای React، رویکرد جدیدی در این زمینه وجود دارد: استفاده از قلاب های سفارشی.
چرا باید منطق را از جزء جدا کنیم؟
قبل از اینکه منطق را از اجزای React خود جدا کنیم، باید دلیل آن را بدانیم.
سازماندهی کد ما به گونه ای که هر تابع یا مؤلفه فقط مسئول یک چیز باشد، این مزیت را دارد که بسیار زیاد است تغییر و نگهداری آسان تر است (دیو و اندرو این را می نامندارتودنسی” در کتابشان برنامه نویس عملگرا).
اعمال این مورد در React به این معنی است که کامپوننت ما تمیزتر و منظم تر به نظر می رسد. به عنوان مثال، قبل از ویرایش UI، نیازی به عبور از دیوار منطق نخواهیم داشت.
سازماندهی کد خود به این صورت نه تنها باعث میشود که بهتر و راحتتر به نظر برسد، بلکه تغییر آن را نیز آسانتر میکند، زیرا تغییر قلاب بر رابط کاربری تأثیر نمیگذارد و بالعکس.
تست کردن نیز در دسترستر است: اگر بخواهیم میتوانیم منطق را جدا از رابط کاربری آزمایش کنیم. با این حال مهمترین مزیت برای من این است که چگونه این رویکرد کد من را سازماندهی می کند.
چگونه منطق را با قلاب های React جدا کنیم
برای جدا کردن منطق از مؤلفه خود، ابتدا یک قلاب سفارشی ایجاد می کنیم.
بیایید این جزء را به عنوان مثال در نظر بگیریم. مقدار نمایی عدد پایه و توان را محاسبه می کند:
می توانید کد منبع کامل را پیدا کنید اینجا کلیک نمایید.
کد به شکل زیر است:
export const ExponentCalculator = () => {
const [base, setBase] = useState(4);
const [exponent, setExponent] = useState(4);
const result = (base ** exponent).toFixed(2);
const handleBaseChange = (e) => {
e.preventDefault();
setBase(e.target.value);
};
const handleExponentChange = (e) => {
e.preventDefault();
setExponent(e.target.value);
};
return (
<div className="blue-wrapper">
<input
type="number"
className="base"
onChange={handleBaseChange}
placeholder="Base"
value={base}
/>
<input
type="number"
className="exponent"
onChange={handleExponentChange}
placeholder="Exp."
value={exponent}
/>
<h1 className="result">{result}</h1>
</div>
);
};
این ممکن است قبلاً خوب به نظر برسد، اما به خاطر این آموزش، فقط تصور کنید که منطق بیشتری در اینجا وجود دارد.
به عنوان اولین قدم، ما این کار را انجام خواهیم داد منطق را به یک قلاب سفارشی منتقل کنید و آن را داخل کامپوننت خود صدا بزنید.
const useExponentCalculator = () => {
const [base, setBase] = useState(4);
const [exponent, setExponent] = useState(4);
const result = (base ** exponent).toFixed(2);
const handleBaseChange = (e) => {
e.preventDefault();
setBase(e.target.value);
};
const handleExponentChange = (e) => {
e.preventDefault();
setExponent(e.target.value);
};
return {
base,
exponent,
result,
handleBaseChange,
handleExponentChange,
};
};
export const ExponentCalculator = () => {
const {
base,
exponent,
result,
handleExponentChange,
handleBaseChange,
} = useExponentCalculator();
// ...
};
ما می توانیم این قلاب را به a منتقل کنیم فایل جداگانه برای جدایی برجسته تر از نگرانی ها.
علاوه بر این، ما می توانیم قلاب خود را به عملکردهای کوچکتر و قابل استفاده مجدد تقسیم کنیم. در این صورت فقط می توانیم استخراج کنیم calculateExponent
.
useExponentCalculator.js
const calculateExponent = (base, exponent) => base ** exponent;
const useExponentCalculator = () => {
const [base, setBase] = useState(4);
const [exponent, setExponent] = useState(4);
const result = calculateExponent(base, exponent).toFixed(2);
// ...
};
آزمایش این توابع بسیار ساده تر از آزمایش کل کد مؤلفه از مثال اول است. ما میتوانیم آنها را با هر کتابخانه آزمایشی Node.js آزمایش کنیم، که حتی نیازی به پشتیبانی از مؤلفههای React ندارد.
ما اکنون کد مخصوص چارچوب خود (React) را در کد کامپوننت و هوک داریم، در حالی که منطق کسب و کار ما در توابع مختلفی که بعداً تعریف کردیم (که فریم ورک آگنوستیک هستند) زندگی می کند.
بهترین شیوه
نامگذاری
من دوست دارم قلاب های سفارشی خود را پس از کامپوننت به عنوان ترکیبی از نام گذاری کنم use
و نام جزء (مثلاً useExponentCalculator
). من سپس به همان را بایگانی کنید به عنوان قلاب
ممکن است بخواهید از یک قرارداد نامگذاری متفاوت پیروی کنید، اما من توصیه می کنم ثابت ماندن در پروژه شما
اگر بتوانم از قسمتهایی از یک هوک سفارشی دوباره استفاده کنم، معمولاً آن را به فایل دیگری در زیر منتقل میکنم src/hooks
.
زیاده روی نکنید
سعی کنید عملگرا باشید. اگر یک جزء فقط چند خط JS داشته باشد، لازم نیست منطق را از هم جدا کنید.
CSS-in-JS
اگر از کتابخانه CSS-in-JS استفاده می کنید (useStyles
، ممکن است بخواهید این کد را به فایل دیگری نیز منتقل کنید.
می توانید آن را به همان فایلی که قلاب است منتقل کنید. با این حال، ترجیح میدهم یا آن را بالای کامپوننت در همان فایل نگه دارم یا اگر خیلی بزرگ شد، آن را به فایل خودش منتقل کنم.
نتیجه
چه فکر میکنید که استفاده از قلابهای سفارشی کد شما را بهبود میبخشد یا خیر، در نهایت به ترجیحات شخصی بستگی دارد. اگر پایگاه کد شما منطق زیادی را شامل نمی شود، مزایای این الگو برای شما چندان مرتبط نخواهد بود.
قلاب های سفارشی تنها یک راه برای افزایش مدولار بودن هستند. من نیز به شدت توصیه می کنم تقسیم اجزا و عملکردها به قطعات کوچکتر و قابل استفاده مجدد در صورت امکان
این موضوع در سطح کلی تری نیز مورد بحث قرار می گیرد برنامه نویس عملگرا. من مقالهای نوشتم که موضوعات مورد علاقهام را در کتاب پوشش میدهد، بنابراین اگر به شما علاقهمند است، حتماً این کار را انجام دهید بررسی کنید.