کامپوننت در برنامه نویسی چیست؟ بررسی کامپوننت در تکنولوژی های مختلف

محمدامین سعیدی راد
1400/05/14
130
کامپوننت در برنامه نویسی چیست؟ بررسی کامپوننت در تکنولوژی های مختلف

کامپوننت در برنامه نویسی چیست؟

کامپوننت در برنامه نویسی چیست؟ اگر در حوزه برنامه نویسی وب (مخصوصا فرانت اند) فعالیت داشته باشید، قطعا کلمه کامپوننت را شنیده اید و ممکن است برایتان سوال باشد که کامپوننت چیست؟

در این مقاله قصد داریم به سوال “کامپوننت در برنامه نویسی چیست” پاسخ دهیم و مزایا و معایب استفاده از کامپوننت را هنگام توسعه مورد بررسی قرار دهیم.

پس اگر دوست دارید معنی کلمه کامپوننت و همچنین نحوه استفاده و مزایا و معایب آن را بدانید، این مقاله را مطالعه کنید.

کامپوننت چیست؟

کلمه کامپوننت در لغت به معنی جزء، قسمت و تکه است. کامپوننت (Component) یعنی یک قسمت کوچک از یک شی بزرگ؛ به عنوان مثال یک شهر از یک کشور، یک کامپوننت از آن کشور به شمار می رود.

دقیقا به همین صورت کلمه کامپوننت در برنامه نویسی نیز یعنی قسمت کوچکی از کل پروژه.

به عنوان مثال قسمت Header یا Footer از وب سایت شما یک کامپوننت به شمار می رود. اگر بخواهیم یک مثال بهتر و واضح تر بزنیم، قسمت دوره های وب سایت سبزلرن را در نظر بگیرید:

کامپوننت در برنامه نویسی چیست؟

می توانیم کل قسمت دوره ها را یک کامپوننت  در نظر گرفت. همچنین هر کدام از باکس دوره ها نیز یک کامپوننت هستند که داخل کامپوننت دوره ها استفاده شده اند.

یک مثال دیگر این که هر وب سایت را یک پازل و هر سکشن از وب سایت را یک تکه از آن پازل در نظر بگیرید. به این صورت که تکه های پازل کنار هم قرار گرفته و در نهایت پازل نهایی (وب سایت) ساخته می شود.

پس تا این قسمت مفهوم کامپوننت را یاد گرفتیم و همچنین متوجه شدیم که می توانیم کامپوننت ها را داخل یک دیگر استفاده کنیم.

همچنین شما میتوانید در سایت whatis.techtarget نیز در این رابطه مقالاتی مطالعه نمایید .

در قسمت های بعدی با مبحث کامپوننت بیشتر آشنا خواهیم شد.

کامپوننت در ری اکت

همان طور که می دانید ری اکت یکی از لایبرری (کتابخانه) های زبان برنامه نویسی جاوا اسکریپت است که امروزه بازار کار فوق العاده ای دارد.

ری اکت یک لایبرری کامپوننت بیس است. به این معنی که هر قسمت از وب سایت را به صورت کامپوننت های جداگانه در نظر می گیریم و سپس آن ها را در کنار همدیگر قرار می دهیم و با در کنار هم قرار دادن آن ها وب سایت مورد نظرمان ساخته می شود.

به عنوان مثال اگر بخواهیم کامپوننت های صفحه اصلی یک فروشگاه اینترنتی را در نظر بگیریم، می توان به Header، NavBar، Products، PopularProducts، Footer و … اشاره کرد.

به تصویر زیر که از داکیومنت رسمی ری اکت گرفته شده است توجه کنید:

کامپوننت در برنامه نویسی چیست؟

همان طور که مشاهده می کنید یکی از ویژگی های ری اکت Component Based بودن آن است که مفهومش بالاتر توضیح داده شد.

پس در این قسمت هم متوجه شدیم که لایبرری ری اکت یک لایبرری کامپوننت بیس است و به ما کمک می کند تا پروژه مورد نظرمان را سازماندهی شده پیش ببریم.

چرا باید کامپوننت بیس توسعه دهیم؟

کامپوننت در برنامه نویسی چیست؟

اما ممکن است برایتان سوال باشد که چرا باید پروژه خود را به صورت کامپوننت بیس پیش ببریم و استفاده از کامپوننت چه مزیت هایی دارد.

در خیلی از پروژه هایی که تا به حال با Vanilla Js توسعه داده اید در انتهای پروژه با باگ ها و مشکلاتی روبرو شدید و پیدا کردن و فیکس کردن آن به شدت درگیر شده و مدت زمان زیادی را صرف کرده اید.

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

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

مزایای بعدی استفاده از کامپوننت این است که شما می توانید پروژه خودتان را با کنترل بالاتر توسعه دهید و مدیریت بیشتری روی پروژه مورد نظر داشته باشید.

به عنوان مثال فرض کنید بعد از مدت ها از توسعه پروژه قصد دارید فیچری را به پروژه خودتان اضافه کنید. در این صورت به راحتی و در مدت زمان کم می توانید فیچر مورد نظرتان را به پروژه مورد نظر اضافه کنید.

مزایای بعدی استفاده از کامپوننت قابلیت استفاده مجدد و در نتیجه کاهش حجم سورس کد پروژه است. شما می توانید یک قسمت از وب سایت را یک کامپوننت در نظر گرفته و آن را چندین بار استفاده کنید.

به عنوان مثال تصویری از وب سایت سبزلرن که بالاتر مشاهده کردید را در نظر بگیرید. سه دوره متفاوت داریم که می توانیم یک کامپوننت تحت عنوان Course ایجاد کرده و 3 بار از آن استفاده کنیم.

به همین راحتی باعث می شود سورس کد پروژه شما کاهش پیدا کند.

این 3 مورد فقط چند مورد محدود از مزایای استفاده از کامپوننت است که در این قسمت مورد بررسی قرار دادیم.

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

1 | توسعه و مدیریت بهتر

2 | دیباگینگ راحت تر

3 | پرفورمنس بهتر

4 | تست نویسی راحت تر

و … را دارد.

آموزش جاوا اسکریپت

آیا استفاده از کامپوننت معایب هم دارد؟

در قسمت قبلی چندین مورد از مزایای استفاده از کامپوننت را مورد بررسی قرار دادیم. ممکن است برایتان سوال باشد که استفاده از کامپوننت معایبی را هم به دنبال دارد یا نه.

به طور کلی استفاده از کامپوننت هیچ عیب و ایرادی ندارد اما برخی از افراد معتقد هستند که تقسیم برنامه به کامپوننت های کوچک تر زمان زیادی از آن ها می گیرد  این موضوع را یک ایراد برای برنامه نویسی کامپوننت بیس به شمار می آورند.

به قول معروف “هر که طاووس خواهد، جور هندوستان کشد”. پس برای به دست آوردن مزایایی که در قسمت قبلی گفته شد، باید زمان زیادی بگذاریم.

پس در این قسمت نتیجه می گیریم که زمانبر بودن برنامه نویسی کامپوننت بیس را یک ضعف به حساب نیاوریم. چون این زمانبر بودن قابلیت های خوبی در اختیار ما قرار می دهد.

چه زمانی باید از کامپوننت استفاده کرد؟

طبق توصیه و پیشنهاد داکیومنت اصلی لایبرری ری اکت تا جایی که می توانیم باید پروژه خود را به کامپوننت های کوچک تقسیم کنیم.

مفهوم کامپوننت به وجود آمده است تا بتوانیم حجم سورس کد خود را کاهش داده و کد های کمتری را بنویسیم.

پس به طور کلی قسمتی از وب سایت را باید کامپوننت کنیم که بیشتر از یک بار استفاده شده باشد.

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

انواع کامپوننت ها در لایبرری ری اکت

کامپوننت در برنامه نویسی چیست؟

تا این قسمت با مفهوم کامپوننت و همچنین با مزایا و معایب آن آشنا شدیم. در این قسمت قصد داریم انواع کامپوننت در لایبرری ری اکت را مورد بررسی قرار دهیم.

قبل از این که مطالعه این قسمت را ادامه دهید خدمتتان عرض کنم که کار با کامپوننت های ری اکت نیازمند آشنایی با مبحث class و function در جاوا اسکریپت است.

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

  1. کامپوننت کلاسی (Class Based Component)
  2. کامپوننت تابعی (Functional Component)

کامپوننت های Class Base

کامپوننت در برنامه نویسی چیست؟ همان طور که از اسم این دسته از کامپوننت ها مشخص است، به کمک class تعریف می شوند.

برای استفاده از یک کامپوننت کلاسی ابتدا یک class تعریف می کنیم و سپس داخل آن سازنده و متد های لازم را پیاده سازی می کنیم. همان طور که می دانید هر class یک متد کانستراکتور (سازنده) دارد که اولین متدی است که هنگام استفاده از کلاس فراخوانی می شود.

اما قبل از تعریف کلاس مورد نظر باید این نکته را بدانید که کامپوننت های کلاسی ری اکت از یک کلاس دیگر به اسم Component Class ارث بری می کند. پس برای همین منظور قبل از تعریف کامپوننت مورد نظر، کلاس Component را از ماژول react در صفحه مورد نظر import می کنیم.

کد زیر یک کامپوننت کلاسی است که فعلا فقط یک سازنده دارد:

import React, { Component } from 'react'

class Test extends Component {
	constructor () {

	}
}

export default Test

همان طور که در کد های بالا مشاهده می کنید یک کامپوننت کلاسی ایجاد کردیم که از کلاس Component ارث بری می کند و یک کانستراکتور نیز دارد.

همان طور که بالاتر گفته شد، هر کامپوننت کد های قسمتی از وب سایت ها شامل می شوند و این را می دانیم که ظاهر و template کلی وب سایت به کمک Html و Css پیاده سازی می شود.

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

در کامپوننت های کلاسی متدی به اسم render وجود دارد که کد های Html آن کامپوننت را return می کند. البته در توسعه وب سایت با لایبرری ری اکت دیگر خبری از Html نیست و کد های ما به صورت JSX نوشته می شوند.

در مقاله های قبلی به طور مفصل در مورد JSX صحبت کردیم و دز این مقاله قصد ندارم توضیح زیادی ارائه دهم اما در این حد بدانید که JSX مخفف Java Script Xml می باشد و به این معنی است که ما کدهای Html را به صورت xlm داخل صفحات جاوا اسکریپت پیاده سازی می کنیم.

برای درک بهتر به کد های زیر توجه کنید:

import React, { Component } from 'react'

class Test extends Component {
	constructor () {

	}
	
	render () {
		return (
			<div>SabzLearn.ir</div>
		)
	}
}

export default Test

همان طور که مشاهده می کنید یک متد به اسم render پیاده سازی کردیم و کدهای Html مورد نیاز با داخل آن return کردیم.

اما در انتهای کد ها کدی تحت عنوان export default نوشته است که ممکن است کاربرد آن برای شما سوال باشد.

همان طور که در ابتدای مقاله گفته شد، ما میتوانیم کامپوننت های مختلف را داخل همدیگر استفاده کنیم. برای این منظور هر کامپوننت را ابتدا باید export کنیم تا در قسمت های دیگر بتوانیم آن را import کرده و از آن استفاده کنیم.

کلمه export در لغت به معنی صادر کردن و کلمه import به معنی وارد کردن است. کامپوننت نوشته شده را export می کنیم تا در صفحات مورد نیاز آن را import کرده و از آن استفاده کنیم.

پس در این قسمت مفهوم export و import را نیز متوجه شدید.

کامپوننت های Functional

همان طور که از اسم این دسته از کامپوننت ها مشخص است، به کمک یک فانکشن (تابع) تعریف می شوند. شما برای پیاده سازی یک فانکشنال کامپوننت می توانید از انواع مختلف فانکشن ها مثل arrow function، expression component و … استفاده کنید.

همان طور که می دانید در یک فانکشن بر خلاف کلاس ها خبری از کانستراکتور و ارث بری نیست. برای تعریف یک کامپوننت فانکشنال ابتدا یک فانکشن با اسم مورد نظر و دلخواه تعریف می کنیم و سپس داخل آن JSX مورد نیاز را پیاده سازی کرده و سپس آن را برای استفاده در کامپوننت های دیگر export می کنیم.

به کد زیر توجه کنید:

import React from 'react'

const Test = () => {
	return (
		<div>
			SabzLearn.ir
		</div>
	)
}

export default Test

همان طور که مشاهده می کنید یک فانکشن به صورت Arrow پیاده سازی کرده و داخل آن کد های JSX مورد نیاز را نوشته و در نهایت آن را export می کنیم.

آموزش جاوا اسکریپت

یک نکته خیلی مهم در مورد کامپوننت ها

در مثال هایی که بالاتر زده شد، فقط یک تگ div داشتیم که متنی را نمایش می داد. اما اگر بخواهیم چندین تگ را return کنیم، ری اکت به ما خطایی تحت عنوان “JSX expressions must have one parent element” را نمایش می دهد.

این خطا به این معنی است که شما مجاز هستید که فقط یک المنت را به عنوان والد return کنید.

به عنوان مثال به تکه کد زیر توجه کنید:

import React from 'react'

const Test = () => {
	return (
		<div>
			SabzLearn.ir
		</div>
		<div>
			Java Script Course
		</div>
	)
}

export default Test

همان طور که مشاهده می کنید در این کامپوننت دو تگ div را return کرده ایم که اگر همچین پروژه ای را اجرا کنیم، با خطا مواجه خواهیم شد. با توجه به مفهوم خطا که بالاتر گفته شد، شما می توانید فقط و فقط یک المنت را به عنوان والد return کنیم. اگر بخواهیم دو یا چندین تگ div را return کنیم، باید تگ های مورد نیاز را داخل یک والد قرار دهیم تا فقط یک والد return شده و با همچین خطایی مواجه نشیم.

به عنوان مثال به کد زیر توجه کنید:

import React from "react";

const Test = () => {
  return (
    <div>
      <div> SabzLearn.ir </div>
      <div> Java Script </div>
    </div>
  );
};

export default Test;

همان طور که مشاهده می کنید، دو تگ div را داخل یک تگ div به عنوان والد return می کنیم و به همین راحتی مشکل موجود برطرف می شود.

راه حل بهتری نیز برای رفع این مشکل وجود دارد که استفاده از Fragment است و در مقاله های بعدی آن را به طور کامل مورد بررسی قرار خواهیم داد.

نحوه استفاده از یک کامپوننت داخل کامپوننت دیگر

کامپوننت در برنامه نویسی چیست؟

در قسمت های قبلی به کلماتی مثل export و import اشاره کردیم و متوجه شدیم که به کمک این کلمات کلیدی از کامپوننت های مختلف داخل همدیگر استفاده کنیم.

کامپوننت زیر را که کامپوننت Footer است در نظر بگیرید:

import React from "react";

const Footer = () => {
  return (
    <div>
      <div> This is footer component </div>
    </div>
  );
};

export default Footer;

در کد بالا یک کامپوننت با اسم Footer پیاده سازی کرده و آن را export کرده ایم. فرض کنید در صقحه لاگین وب سایت قصد داریم از آن استفاده کنیم.

به کد های زیر توجه کنید:

import React from 'react'
import Footer from './components/Footer'

 const Login = () => {
	return (
		<div>
			<h1>اینجا صفحه لاگین می باشد</h1>
			<Footer />
		</div>
	)
}

export default Login

همان طور که در کدهای بالا مشاهده می کنید، ابتدا کامپوننت Footer را import کرده و بعد از پیاده سازی کد های مربوط به فرم لاگین (اینجا به یک h1 بسنده کردیم) از کامپوننت Footer استفاده کرده ایم.

شما به همین راحتی می توانید کامپوننت های مختلف را ایجاد و export کرده و از آن ها در داخل کامپوننت های دیگر استفاده کنید.

کامپوننت در برنامه نویسی چیست و از کدام نوع کامپوننت استفاده کنیم؟

بنا به پیشنهاد داکیومنت رسمی ری اکت بهتر است که عمدتا از کامپوننت های فانکشنال استفاده کنیم.

به عنوان مثال فرض کنید قصد داریم پیغام Hello World را در یک تگ h1 نمایش دهیم. اگر بخواهیم این پیغام را به کمک فانکشنال کامپوننت پیاده سازی کنیم به صورت زیر خواهد بود:

const App = props => <div>Hello World</div>

همان طور که مشاهده می کنید توانستیم پیغام مورد نظر را در یک خط به کمک کامپوننت فانکشنال نمایش دهید.

حالا نوبت کامپوننت های کلاسی است. اگر بخواهیم پیغام Hello World را به کمک کامپوننت های کلاسی نمایش دهید به صورت زیر خواهد بود:

class App extends React.Component {
    render () {
        return (
            <div>Hello World</div>
        )
    }
}

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

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

پس تا این قسمت متوجه شدیم که کامپوننت های فانکشنال حجم سورس کد پایین تری داشته و مدت زمان کمتری را از شما برای توسعه می گیرند.

کد زیر همان کد بالا برای کامپوننت فانکشنال است که توسط Babel ترجمه شده است:

کامپوننت در برنامه نویسی چیست؟

و اما در ادامه به به خروجی کد کامپوننت کلاسی برای Hello World که توسط Babel توجمه شده است می پردازیم:

کامپوننت در برنامه نویسی چیست؟

همان طور که در دو تصویر بالا متوجه شدید علاوه بر کم حجم بودن کد کامپوننت فانکشنال، پس از ترجمه نیز کم حجم هستند و مدت زمان کمتری برای ترجمه آن ها طول می کشد و ترجمه آن ها راحت تر است.

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

ممکن است برایتان سوال باشد که چه زمانی مجبور به استفاده از کلاس کامپوننت ها هستیم. کامپوننت های کلاسی متد های بیشتری در زمینه LifeCycle در اختیارمان قرار می دهند و مواقعی که نیازی به آن ها داشته باشیم، از کامپوننت های کلاسی استفاده کرده و در غیر این صورت از کامپوننت های فانکشنال استفاده می کنیم که نیاز ما را به طور کامل برطرف خواهند کرد.

آیا مفهوم کامپوننت فقط در ری اکت مطرح است؟

جواب این سوال منفی است و مفهوم کامپوننت فقط به لایبرری ری اکت محدود نمی شوند. مفهوم و اصطلاح کامپوننت در فریمورک هایی مثل Vue Js و Angular Js نیز مطرح بوده و آن ها هم از کامپوننت استفاده می کنند.

به عنوان مثال تکه کد زیر کد های یک کامپوننت در فریمورک Vue Js است:

Vue.component('custom-input', {
  props: ['value'],
  template: `
    <input
      v-bind:value="value"
      v-on:input="$emit('input', $event.target.value)"
    >
  `
})

همان طور که در تکه کد بالا مشاهده می کنید یک کامپوننت به اسم custom-input ایجاد کرده ایم که به ازای هر بار استفاده، template مورد نظر را render کرده و روی Dom به کاربر نمایش داده می شود.

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

ایجاد و استفاده راحت تر از کامپوننت ها

کامپوننت در برنامه نویسی چیست؟

اگر شما بخواهید یک کامپوننت کلاسی یا فانکشنال در یک پروژه ری اکتی ایجاد کنید، باید کلمات کلیدی لازم مثل const، export، default و … را به طور دستی تایپ کنید و این کار زمان زیادی از شما خواهد گرفت؛ پس در نتیجه کار بهینه و معقولی نیست.

برای این کار یکی اکستنشن برای کد ادیتور Visual Studio Code وجود دارد به اسم ES7 React/Redux/GraphQL/React-Native snippets (اسمش چه طولانیه :|) که به شما کمک می کند تا با کلمات مخفف  کوتاه، کدهای زیادی را در صفحه مورد نظرتان ایجاد کنید.

به عنوان مثال شما برای ایجاد یک کامپوننت کلاسی از کلمه rcc را نوشته و tab را می زنیم و به این ترتیب کد های لازم برای یک کامپوننت کلاسی ایجاد می شود.

همچنین برای ایجاد یک کامپوننت فانکشنال از کلمه rfc استفاده می شود. جالب است بدانید که rcc مخفف React Class Component بوده و کلمه rfc مخفف React Functional Component می باشد.

شما با نوشتن کلمه rcc کد های زیر برایتان ایجاد می شود:

import React, { Component } from 'react'

export default class FileName extends Component {
  render() {
    return <div> $2 </div>
  }
}

و همچنین با کلمه rfc کد های زیر ایجاد می شوند:

import React from 'react'

export default function $1() {
  return <div> $0 </div>
}

این فقط دو مورد از شورتکات های این اکستنشن هستند و شورتکات های زیادی نیز در اختیارتان قرار می دهد تا شما بتوانید سرعت توسعه بالایی داشته و در مدت زمان شما صرفه جویی شود.

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

سخن پایانی

کامپوننت در برنامه نویسی چیست؟ مبحث کامپوننت یکی از مهم ترین و پر استفاده ترین مباحث برنامه نویسی {فرانت اند} است که شما باید با آن آشنایی کاملی داشته باشید.

در این مقاله سعی کردیم به مفهوم کامپوننت و کاربرد ها، مزایا و معایب آن اشاره کنیم.

ری اکت یکی از لایبرری های زبان جاوا اسکریپت است که امروزه بازار کار فوق العاده و جامعه آماری بالایی دارد که یادگیری آن را به شما پیشنهاد می کنم.

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

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

آموزش جاوا اسکریپت

برای این که بتوانید مفاهیم مطرح شده در این مقاله را بهتر و عمیق تر یاد بگیرید، پیشنهاد میکنم ویدئوی این مقاله را نیز حتما مشاهده کنید.

هر گونه سوال، ابهام و انتقادی در مورد مقاله و مبحث کامپوننت داشتید می توانید در قسمت کامنت های مقاله مطرح کنید.

امیدوارم این مقاله برای شما کاربران عزیز مفید واقع شده باشد.

تا مقاله ای دیگر خدا یار و نگهدارتان.

محمدامین سعیدی راد

نظرات

ثبت نظر جدید
ali_ultraa | کاربر
1402/12/28

عالی و خیلی مفید بود برام 👌🏻♥️

محمدامین سعیدی راد | مدرس
1402/12/28

🙏❤️

porya84 | کاربر
1402/10/09

ممنون بابت این که به فکر همه چی هستید

محمدامین سعیدی راد | مدرس
1402/10/09

❤️❤️

آموزش جاوا اسکریپت