سه چالش اصلی که توسعهدهندگان با آن روبهرو هستند
ابتدا اجازه دهید بهسراغ سه چالش اصلی یعنی قابلیت نگهداری، عدم تسلط بر مفاهیم اولیه و گسترشپذیری برویم که هر توسعهدهنده React با آنها روبهرو میشود.
قابلیت نگهداری
قابلیت نگهداری ارتباط مستقیمی با قابلیت استفاده مجدد دارد. نرمافزارهای اولیه مولفههای کمی داشتند که روند اجرای آنها را سریعتر و نگهداری از آنها را سادهتر میکرد، اما هنگامی که نیازها شروع به رشد کردند، مولفههای پیچیدهتری به نرمافزارها اضافه شدند. همین مسئله باعث شد تا قابلیت نگهداری از برنامهها سختتر شود.
بهطور معمول، توسعهدهندگان در طول دوران کاری خود مولفههای مختلفی را طراحی یا از آنها استفاده میکنند که هر یک برای مقاصد خاصی طراحی شدهاند. بهطور مثال، JSX از رندرهای شرطی زیاد (عملگرهای سهتایی و عملگرهای && ساده)، نام کلاسهایی که بهصورت شرطی استفاده میشوند یا مولفهای که دارای یک دستور سوئیچ بزرگ است استفاده میکند. علاوه بر این، مقادیر زیادی از prop و state وجود دارند که هر یک خروجی مختلفی را ارائه میکنند.
این تکنیکها به خودی خود هیچ اشکالی ندارند، اما مهم این است که زمان استفاده درست از یک مولفه را بدانیم و بیشازاندازه از یک مولفه برای انجام کارهای مختلف استفاده نکنیم. یکی از مشکلات بزرگی که برنامهنویسان با آن روبهرو هستند، درک درست عملکرد یک مولفه است. به بیان دقیقتر، هر چه یک مولفه پیچیدگیهای زیادی داشته باشد و نتایج متفاوتی ارائه کند (چندریختی)، حفظ ترکیب نحوی آن دشوارتر میشود. تنها راه غلبه بر این مشکل، تمرین زیاد، بازبینی مستمر پروژهها و ویرایش کدهایی است که ممکن است نیازمند ویرایش باشند.
برای این منظور باید از تکنیکهایی همچون تست واحد (Unit Test) برای ارزیابی فنی کدهای مورد استفاده در برنامههای کاربردی استفاده کنید. تست واحد و آزمایشهای کاربردی از مباحثی هستند که مورد علاقه توسعهدهندگان نیستند و بیشتر آنها سعی میکنند این بخش را نادیده بگیرند. با اینحال، آزمایش ماژولهای مختلف یک برنامه کاربردی کمک میکنند نرمافزاری را طراحی کنید که کاربر نهایی به سادهترین شکل قادر به استفاده از آن است.
عدم تسلط بر مفاهیم اولیه
یکی دیگر از مشکلات توسعهدهندگان هنگام کار با React، عدم تسلط بر ترکیب نحوی React است. متاسفانه، برخی افراد بهسرعت بهسراغ مفاهیم متوسط یا پیشرفته میروند، بدون آنکه پایه محکمی در مفاهیم اولیه داشته باشند. عدم تسلط بر مفاهیم اولیه مشکلات مختلفی برای توسعهدهندگان ایجاد کند. بهطور مثال، تنها زمانی قادر به استفاده از چرخه عمر مولفهها مختلف هستید، که آشنایی کاملی با آنها داشته باشید.
مقیاسپذیری
همانگونه که اشاره کردیم، مقیاسپذیری ارتباط نزدیکی با قابلیت نگهداری دارد و قاعدهای کلی و مهم در دنیای نرمافزار است. نکتهای که باید به آن دقت کنید این است که ساخت نرمافزارهای عالی، محدود به تجربه کاربری، الگوهای کد تمیز یا معماری هوشمندانه نیست و مقیاسپذیری اصل بسیار مهمی است که باید به آن دقت کنید، زیرا تاثیر مستقیمی روی کیفیت نرمافزار دارد. سنجههای مختلفی باعث میشوند تا مقیاسپذیری یک نرمافزار افزایش پیدا کند. اگر هنگام ساخت برنامههای کاربردی، استقرار ماژولهای نرمافزاری و سازماندهی ساختار پروژه به قابلیت نگهداری و مقیاسپذیری دقت کنید، سورسکدهای خوانا و تمیزی خواهید نوشت که زمان بازبینی یا افزودن ماژولهای جدید به آنها را کوتاهتر میکند.
چگونه React را یاد بگیریم
یکی از مهمترین، چالشهایی که افراد برای ورود به دنیای برنامهنویسی وب دارند، نحوه یادگیری موضوعات جدید است. در ادامه قصد داریم بهسراغ بررسی بهترین روشهای یادگیری React برویم.
React را بهشکل مرحله به مرحله بیاموزید
یکی از بزرگترین مشکلات علاقهمندان به یادگیری ریاکت و دیگر زبانهای برنامهنویسی، روند یادگیری سریع است. بهترین روش یادگیری مباحثی مثل برنامهنویسی، رویکرد یادگیری مستمر و آهسته است. به این معنا که هر جلسه آموزشی پیرامون یک تا سه نکته باشد تا مفاهیم بهطور کامل در ذهن نقش ببندند. متاسفانه، کاری که برخی آموزشگاهها انجام میدهند این است که سعی میکنند در یک بازه کوتاه دو ماهه که هر جلسه آن بیش از دو تا سه ساعت است، علاقهمندان به مباحث برنامهنویسی را بمباران اطلاعاتی کنند. رویکردی که در نهایت افراد نکات خیلی کمی را میآموزند. همین مسئله برای یادگیری React نیز صدق میکند. شما نمیتوانید یک آسمان خراش را روی زیربنایی سست استوار کنید و انتظار داشته باشید که محکم باشد.
این موضوع ممکن است برای برخی از شما بدیهی بهنظر برسد، اما من توسعهدهندگانی را دیدهام که بدون درک اصول اولیه بهسراغ یادگیری مفاهیم متوسط یا پیشرفته React رفتهاند. اگر دوست دارید ریاکت را بهشکل اصولی بیاموزید، ابتدا باید بهسراغ یادگیری جاوااسکریپت بروید. مطمئن باشید اگر این توصیه را رعایت کنید، موفق خواهید بود.
دانستن اصول اولیه به تنهایی کافی نیست. دانستن این موضوع که ریاکت در پسزمینه چه کارهایی را انجام میدهد، اهمیت زیادی دارد. اگر میخواهید یک توسعهدهنده خوب ریاکت شوید، باید شناخت دقیقی در ارتباط با ابزاری که از آن استفاده میکنید بهدست آورید. یادگیری معماری ریاکت کمک میکند، پروژههایی را که برای مشتریان طراحی میکنید به زبان ساده شرح دهید.
همچنین، در هنگام رویارویی با مشکلات، زمان کمتری صرف اشکالزدایی برنامه میشود. همچنین، به این نکته مهم دقت کنید که شما نمیتوانید همه چیز را بهشکل تئوری بیاموزید و باید وقت زیادی را صرف کدنویسی کنید تا در نهایت مشکلاتی را که پروژههای مختلف با آن روبهرو میشوند درک کنید.
برای داشتن یک پایه محکم در React باید چه چیزی را یاد بگیریم؟
یکی از مهمترین مباحثی که باید روی یادگیری آن متمرکز شوید، هوکها (Hooks) هستند، زیرا به یک استاندارد مهم مرتبط با ریاکت تبدیل شدهاند و همهجا استفاده میشوند، بهویژه در ارتباط با بستههای شخص ثالث ریاکت. البته مولفههای دیگری نیز وجود دارند که کاربرد زیادی دارند که از آن جمله باید به useState و useEffect، useMemo، useCallback و useRef اشاره کرد. بهطور کلی، برای یادگیری ریاکت توصیه میشود به فکر یادگیری مفاهیم زیر باشید:
- State چیست؟
- مولفههای پردازش مجدد (Re-rendering) چیستند و چگونه کار میکنند؟
- چگونه رندرهای مجدد را فعال کنیم؟
- چرخه عمر مولفههای مختلف به چه صورتی است و مولفههای ریاکت به چه نحوی با یکدیگر در تعامل هستند؟
- DOM مجازی چیست؟
- پردازش سمت کلاینت (Client Side Rendering) و پردازش سمت سرور (Server Side Rendering) چه مزایایی دارند؟
- مولفههای کنترلشده و مولفههای کنترلنشده چه تفاوتهایی دارند؟
- State Lifting به چه معنا است؟
- حداقل یک فناوری مدیریت وضعیت سراسری (Context API، Redux/Toolkit، Recoil) را بیاموزید.
- الگوهای مولفهها را بشناسید تا بتوانید یک الگوی مناسب انتخاب کنید.
چگونه مولفههای تعاملی تمیز، کارآمد و قابل نگهداری بسازیم؟
تفاوت زیادی میان یک برنامهنویس خوب و عالی وجود دارد. یک برنامهنویس خوب، کدهایی مینویسد که اجرا میشوند و برنامه نهایی خطایی تولید نمیکند، اما یک برنامهنویس عالی، فردی است که کدهای بهینهای مینویسد که کمترین میزان استفاده از منابع سیستمی را دارند و برنامه نهایی در زمان کوتاهی اجرا میشود. برای آنکه کدهای ریاکت کارآمدی بنویسید، باید از بهترین شیوهها برای کدنویسی استفاده کنید، بهطوری که اعضا تیم بتوانند بهسادگی کدهایی را که مینویسید درک کنند. برای این منظور باید یک راهنمای سبک (Style Guide) بنویسید که شامل دستورالعملها و نکاتی است که هنگام کدنویسی باید آنها را رعایت کنید. بهعنوان یک برنامهنویس ریاکت از اصول زیر پیروی کنید تا کدهای خوانا و با قابلیت نگهداری بالا بنویسید:
- از مولفههای کاربردی مثل Arrow-Functions استفاده کنید.
- از سبکهای درونخطی (Inline) استفاده نکنید.
- از ساختار واردات مناسب (Import Structure) استفاده کنید.
- کدهای خود را قالببندی و مستندسازی کنید و بعد در اختیار دیگران قرار دهید.
بهطور کلی، یک راهنمای سبک، روش خوبی برای کدنویسی و بهکارگیری بهترین شیوههای کدنویسی است که این اطمینان خاطر را میدهد که تیم شما در مورد موضوعات مهم اطلاعات کافی دارد.
اکنون به این پرسش مهم میرسیم که برنامهنویسان ریاکت برای کدنویسی تمیز، کارآمد و با قابلیت نگهداری بالا باید از چه شیوههایی استفاده کنند؟ در ادامه به برخی از اصول مهم اشاره میکنیم.
از یک ساختار خوب برای سازماندهی فایلها و پوشهها استفاده کنید
سازماندهی فایلها و پوشههای یک برنامه ریاکت با هدف قابلیت نگهداری و مقیاسپذیری ضروری است. یک پوشه باید متناسب با اندازه برنامه و تیم ایجاد شود. در هنگام ساخت پوشه به این نکته مهم دقت کنید که پروژه در گذر زمان بزرگ میشود و تغییرات زیادی در آن اعمال میشود، به همین دلیل بهتر است تخمینی در این زمینه انجام دهید.
Importهای یک پروژه را سازماندهی کنید
اگر تجربه کار با ریاکت را دارید، ممکن است فایلهایی را مشاهده کرده باشید که شامل دستورات import زیادی هستند. همچنین، برخی از برنامههای کاربردی، وابستگیهای (Dependencies) زیادی دارند که کتابخانهها و چارچوبهایی را به پروژه وارد میکنند که برای دسترسی به برخی مولفههای داخلی مثل توابع، سبکها و غیره به آنها نیاز دارید. در چنین شرایطی، ممکن است چیزی شبیه به حالت زیر داشته باشید:
import React, { useState, useEffect, useCallback } from “react”;
import Typography from “@material-ui/core/Typography”;
import Divider from “@material-ui/core/Divider”;
import Title from “../components/Title”;
import Navigation from “../components/Navigation”;
import DialogActions from “@material-ui/core/DialogActions”
import { getServiceURL } from ‘../../utils/getServiceURL”;
import Grid from “@material-ui/core/Grid”;
import Paragraph from “../components/Paragprah”;
import { sectionTitleEnum } from “../../constants”;
import { useSelector, useDispatch } from “react-redux”;
import Box from “@material-ui/core/Box”;
همانگونه که مشاهده میکنید، این روش وارد کردن وابستگیها به یک پروژه، به هیچ عنوان ساختیافته نیست. بهعنوان یک برنامهنویس ریاکت باید importها و وابستگیهای مرتبط با آنها را در کنار یکدیگر قرار دهید تا همهچیز شکل ساختیافته پیدا کنند. قطعه کد زیر این موضوع را نشان میدهد:
import React, { useState, useEffect, useCallback } from “react”;
import Typography from “@material-ui/core/Typography”;
import Divider from “@material-ui/core/Divider”;
import Title from “../components/Title”;
import Navigation from “../components/Navigation”;
import DialogActions from “@material-ui/core/DialogActions”
import { getServiceURL } from ‘../../utils/getServiceURL”;
import Grid from “@material-ui/core/Grid”;
import Paragraph from “../components/Paragprah”;
import { sectionTitleEnum } from “../../constants”;
import { useSelector, useDispatch } from “react-redux”;
import Box from “@material-ui/core/Box”;
هرچه سازماندهی روشنتر باشد، تشخیص کتابخانهها و چارچوبهای خارجی و داخلی از یکدیگر ساده خواهند بود. توسعهدهندگان حرفهای ساختار واردات (Imports) را به سه بخش مختلف ازپیشساختهشده (مثل react)، خارجی (ماژولهای شخص ثالث) و داخلی تقسیم میکنند.
الگوهای پیرامون مولفههای مختلف را بیاموزید
برای آنکه مطمئن شوید کدهای شما با مشکلاتی مثل عدم گسترشپذیری و نگهداری روبهرو نیستند، باید دانش خود در مورد الگوهای مختلف پیرامون مولفههای ریاکت را افزایش دهید. تسلط بر الگوها به این معنا است که شما میدانید چه زمانی از کدام الگو برای مشکل استفاده کنید.
از یک لینتر (linter) و خطمشیهای آن استفاده کنید
لینت (Lint) یا لینتر (linter) یک ابزار تجزیهوتحلیل کد ایستا است که برای نشانهگذاری خطاهای برنامهنویسی، باگها، خطاهای سبکدهی و ساختارهای غیربهینه استفاده میشود. لینتر نهتنها در نظمدهی به importها و وابستگیها به شما کمک میکند، بلکه کمک میکند تا کدهای بهتری بنویسید. هنگامی که از ابزار create-react-app استفاده میکنید، ESLint بهشکل پیکربندیشده در اختیارتان قرار میگیرد، اما امکان سفارشیسازی آن وجود دارد و میتوانید دستورالعملهای خود را به مجموعه قوانین آن اضافه کنید. بهطور کلی، یک لینتر، کد جاوااسکریپتی را که مینویسید ارزیابی میکند و خطاهایی را که به احتمال زیاد هنگام کدنویسی مرتکب شدهاید به شما گوشزد میکند. اصل مهمی که هنگام استفاده از لینتر باید به آن دقت کنید، رعایت قواعد و خطمشیها است. البته این امکان وجود داد تا قواعد را بهطور کلی، برای یک خط کد یا برای کل فایل غیرفعال کنید، اما پیشنهاد میکنیم اینکار را انجام ندهید تا کدهای ساختیافتهای بنویسید. یکی دیگر از مزایای عالی که لینترها در اختیارتان قرار میدهند، ارزیابی سبکها است. این قابلیت بهویژه هنگام کار تیمی ارزشمند میشود. به همین دلیل، پیشنهاد میکنیم کمی وقت صرف کرده و نحوه استفاده از ESLint و JSPrettify را بیاموزید.
کدهای خود را آزمایش کنید
برخی از برنامهنویسان ریاکت از آزمایش کدها فراری هستند و آنرا کاری بیهوده میدانند، شاید این مسئله در مورد پروژههای کوچک کماهمیت باشد، اما در مورد پروژههای بزرگ ضروری است. آزمایش کدها نشان میدهد که شما در کار خود حرفهای هستید و میتوانید نرمافزارهای با کیفیت بالا طراحی کنید. برنامهنویسان حرفهای ریاکت از سه روش تست واحد (Unit Test)، تست یکپارچگی (Integration Test) و تست (End-To-End) استفاده میکنند. زمانی که مشغول نوشتن تستها هستید، باید به مسائل مختلفی فکر کنید. یک مولفه خاص چه کاری باید انجام دهد و چه موارد مهمی را باید هنگام آزمایش کدها مدنظر قرار دهم، آیا میتوانم یک مولفه را بهگونهای بهینه کنم که تنها یک هدف را دنبال کند؟
تستها میتوانند بهعنوان یک مکانیزم مستندسازی نیز استفاده شوند تا توسعهدهنده ریاکت که برنامه شما را مشاهده میکند، متوجه شود بخشهای مختلف نرمافزار قرار است چه کاری انجام دهند و نحوه عملکرد آنها به چه صورتی است.
تایپاسکریپت را ادغام کنید یا حداقل از ابزارهای پیشفرض و نوعهای پایه استفاده کنید
استفاده از تایپاسکریپت (TypeScript) مزایای زیادی دارد که از مهمترین آنها باید به بررسی نوع استاتیک، تکمیل بهتر کدها در محیط توسعه یکپارچه (intellisense)، بهبود تجربه کدنویسی و شناسایی زودهنگام خطاهای نوع هنگام کدنویسی اشاره کرد.
از تکنیکهای lazy-loading و code splitting استفاده کنید
اگر تجربه کار با جاوااسکریپت و ریاکت را داشته باشید، به احتمال زیاد با مفهوم Bundling آشنا هستید. بیشتر برنامههای ریاکت با استفاده از ابزارهایی مانند Webpack ،Rollup یا Browserify اقدام به بستهبندی (Bundle) فایلها میکنند. بستهبندی بهمعنای بررسی فایلهای واردشده (import) و ادغام آنها در یک فایل واحد است که بسته (Bundle) نام دارد. در ادامه، میتوان این بسته را در یک صفحه وب قرار داد. رویکرد فوق یک تکنیک عالی است، اما مشکل بزرگی دارد؛ هنگامیکه برنامه وبمحور رشد میکند، بسته نرمافزاری نیز شروع به رشد میکند، به ویژه زمانی که از کتابخانههای بزرگ شخص ثالث مانند three.js استفاده کنید.
برخی توسعهدهندگان برای حل این مشکل اقدام به بارگذاری کامل یک بسته میکنند، حتا زمانی که تنها به برخی از کدها نیاز است. مشکلی که روش فوق دارد این است که روی عملکرد برنامه تاثیر منفی میگذارد، زیرا بارگذاری برنامه به زمان زیادی نیاز خواهد داشت.
برای پیشگیری از بروز مشکلات فوق، باید از تکنیکی که تقسیم کد (Code Splitting) نام دارد استفاده کرد. در روش فوق، بسته به بخشها و تکههای کوچکی که موردنیاز است، تقسیم میشوند. ابزارهایی مثل Webpack ،Rollup و Browserify بر مبنای این تکنیک کار میکنند. مزیت بزرگی که روش فوق دارد این است که اجازه میدهد باندلهای مختلفی ایجاد کنید و آنها را بهصورت پویا بارگذاری کنید. در این حالت، تنها بخشهایی که نیاز است، بارگیری میشوند که سرعت و عملکرد برنامه را به میزان قابل توجهی بهبود میبخشد.
از try-catch برای رسیدگی به خطاهای فراتر از کرانهها استفاده کنید
این تکنیک برای تشخیص خطاهایی که ممکن است در فراخوانیهای غیرهمزمان رخ دهد موثر است. فرض کنید دادههای پروفایل یک کاربر را از یک واسط برنامهنویسی کاربردی دریافت کردهایم و میخواهیم آنها را در داخل یک مولفه نمایه (Profile Component) نشان دهیم.
const UserProfile = ({ userId }) => {
const [isLoading, setIsLoading] = useState(true)
const [profileData, setProfileData] = useState({})
useEffect(() => {
// Separate function to make of use of async
const getUserDataAsync = async () => {
try {
// Fetch user data from API
const userData = await axios.get(`/users/${userId}`)
// Throw error if user data is falsy (will be caught by catch)
if (!userData) {
throw new Error(“No user data found”)
}
// If user data is truthy update state
setProfileData(userData.profile)
} catch(error) {
// Log any caught error in the logging service
errorService.log({ error })
// Update state
setProfileData(null)
} finally {
// Reset loading state in any case
setIsLoading(false)
}
}
getUserDataAsync()
}, [])
if (isLoading) {
return <div>Loading ...</div>
}
if (!profileData) {
return <ErrorUI />
}
return (
<div>
...User Profile
</div>
)
}
هنگامی که مولفه نصب میشود، یک درخواست GET به واسط برنامهنویسی کاربردی ارسال میکند تا دادههای کاربری مربوط به شناسه userId مرتبط با props را دریافت کند. استفاده از بلوک try-catch کمک میکند هر خطایی را که ممکن است در طول فراخوانی واسط برنامهنویسی کاربردی رخ دهد پیدا کنیم. بهعنوان مثال، این خطا میتواند یک پاسخ 404 یا 500 از واسط برنامهنویسی کاربردی باشد. در این حالت بلوک catch قادر به دریافت کد خطا بهعنوان پارامتر است. اکنون میتوانیم آن را در سرویس ورود به سیستم خود وارد کنیم و وضعیت را متناسب با آن بهروزرسانی کنیم تا یک رابط کاربری خطای سفارشی نشان دهد.
کلام آخر
همانگونه که مشاهده میکنید، دنیای ریاکت با ترفندها و نکات ریزی احاطه شده که تسلط بر آنها کمک میکند کدهای ساختیافته و روشنی را بنویسید. الگوهای کدنویسی دیگری نیز وجود دارند که در این مقاله به آنها اشاره نکردیم. الگوهایی که کمک میکنند امنیت کدهای خود را بهبود بخشید، خصلتهای غیر html را حذف کنید و از مولفههایی مثل useState استفاده کنید. برای اطلاعات بیشتر در ارتباط با ترفندهای دیگر پیشنهاد میکنیم به مقاله زیر مراجعه کنید.
ماهنامه شبکه را از کجا تهیه کنیم؟
ماهنامه شبکه را میتوانید از کتابخانههای عمومی سراسر کشور و نیز از دکههای روزنامهفروشی تهیه نمائید.
ثبت اشتراک نسخه کاغذی ماهنامه شبکه
ثبت اشتراک نسخه آنلاین
کتاب الکترونیک +Network راهنمای شبکهها
- برای دانلود تنها کتاب کامل ترجمه فارسی +Network اینجا کلیک کنید.
کتاب الکترونیک دوره مقدماتی آموزش پایتون
- اگر قصد یادگیری برنامهنویسی را دارید ولی هیچ پیشزمینهای ندارید اینجا کلیک کنید.
نظر شما چیست؟