<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های null</title>
        <link>https://virgool.io/feed/@undefined</link>
        <description>همه چی دون نیستم ولی چیزایی که میدونم و بلد هستم رو به بقیه هم یاد میدم :)</description>
        <language>fa</language>
        <pubDate>2026-06-10 15:10:25</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/1389694/avatar/lZzMrV.jpeg?height=120&amp;width=120</url>
            <title>null</title>
            <link>https://virgool.io/@undefined</link>
        </image>

                    <item>
                <title>آبجکت ها بیشتر از یک آبجکت هستند. متد Object.defineProperty چیست؟</title>
                <link>https://virgool.io/@undefined/%D8%A2%D8%A8%D8%AC%DA%A9%D8%AA-%D9%87%D8%A7-%D8%A8%DB%8C%D8%B4%D8%AA%D8%B1-%D8%A7%D8%B2-%DB%8C%DA%A9-%D8%A2%D8%A8%D8%AC%DA%A9%D8%AA-%D9%87%D8%B3%D8%AA%D9%86%D8%AF-%D9%85%D8%AA%D8%AF-objectdefineproperty-%DA%86%DB%8C%D8%B3%D8%AA-bq7tnm6b218a</link>
                <description>سلام به شما دوستان.خیلیا به آبجکت ها به چشم یک دیتا تایپ ساده که فقط میشه بهشون پراپرتی اضافه کرد، پراپرتی حذف کرد و ادیت کرد نگاه میکنن. ولی آبجکت ها خیلی بیشتر از این ها هستن و ویژگی های جالبی دارن. یکی از این ویژگی های جالب و خفن که شاید خیلیا ازش اطلاع ندارن، ویژگی کانفیگ کردن پراپرتی های آبجکت هست. بله! پراپرتی های آبجکت ها کانفیگ دیفالت دارن و شما میتونید اونجوری که دوست دارید این کانفیگ ها رو تغییر بدید! در ادامه نحوه انجام این کار رو بهتون میگم. امیدوارم از این مقاله لذت ببرید و کلی چیز یاد بگیرید.متد defineProperty از کلاس Object، پراپرتی ای رو با کانفیگی که شما مشخص میکنید به آبجکت مورد نظرتون اضافه میکنه.این متد سه تا آرگیومنت میگیره. این آرگیومنت ها به ترتیب عبارتند از: آبجکت مورد نظر شما که میخواید پراپرتی بهش اضافه کنید - اسم پراپرتی مورد نظرتون که میخواید اضافه کنید به آبجکت - آبجکتی که دارای کانفیگ های مورد نظر شما برای اون پراپرتی هستما بیشتر با پراپرتی های آبجکت کانفیگ این متد کار داریم. آبجکت کانفیگ این متد میتونه پراپرتی های زیر رو بگیره(تایپ هایی که هر پراپرتی باید بگیره جلوی : هست ){
value: any,
cnfigurable: boolean | undefined,
writable: boolean | undefined,
enumerable: boolean | undefined,
get: () =&gt; any,
set: (data) =&gt;  void
}توضیحات هر کانفیگ:value: این پراپرتی برای اینه که شما مقدار دیفالت پراپرتی ای که میخواید به آبجکت اضافه کنید رو مشخص کنید.configurable:اگر این پراپرتی مقدارش true باشه، شما نمیتونید اون پراپرتی ای که به آبجکت اضافه شده رو از آبجکت حذف کنید یا اون رو ادیت کنید. اگر false باشه اون پراپرتی این ویژگی ها رو نداره.writable:این پراپرتی اگر مقدارش true باشه، شما میتونید مقدار جدید با استفاده از عملگر انتساب( = ) بریزید توی اون پراپرتی ای که میخواید به آبجکت اضافه کنید. اگر مقدارش false باشه، اون پراپرتی رو نمیشه ادیت کرد.enumerable:این پراپرتی اگر مقدارش true باشه، اون پراپرتی برای حلقه هایی مثل forin معلوم میشه و همچنین اون پراپرتی توی آرایه ای از پراپرتی ها که Object.keys بر میگردونه وجود خواهد داشت. ولی اگر مقدارش false باشه، اون پراپرتی انگار جزوی از اون آبجکت نمیشه(مثال هست) و توی حلقه ای مثل forin و آرایه پراپرتی های اون آبجکت وجود نخواهد داشت. مقدار دیفالت این کانفیگ false هست.get:این پراپرتی همون فانکشن getter خودمون توی آبجکت ها و کلاس ها هست. این فانکشن حتما یه مقداری باید برگردونه.set: این پراپرتی هم همون فانکشن setter خودمون توی آبجکت ها و کلاس ها هست. این فانکشن حتما باید یه آرگیومنت بگیره.نکته 1:  شما اگر میخواید پراپرتی ای که میخواید به آبجکتی اضافه کنید غیر قابل حذف باشه و همچنین بتونید مقدارش رو ادیت کنید، باید configurable و writable رو true کنید.نکته 2: یک پراپرتی که از نوع getter یا setter هست، فقط میتونه کانفیگ های enumerable، configurable و set یا get رو بگیره. اگر شما غیر از این کانفیگ ها رو همزمان در کنار get یا set اضافه کردید، ارور میگیرید.نکته 3: یک پراپرتی همزمان هم میتونه از نوع get باشه هم میتونه از نوع set باشه.یک مثال از این متد: let user = {}; 
Object.defineProperty(user, &amp;quotname&amp;quot, {  value: &amp;quotJohn&amp;quot, enumerable: true  });حالا که معنا و مفهوم این کانفیگ ها رو فهمیدید، بریم یک مثال از این موارد ببینیم.ما یک فانکشنی داریم که برای به دنیا اوردن یک فرد مناسب هست و یه جورایی شناسنامه فرد به دنیا اومده رو بهش میده. این فانکشن مشخصات یک فرد که عبارتند از نام، نام خانوادگی، محل تولد، نام پدر، نام مادر و ملیت رو میگیره. به این شکل:function born(name, lastName, birthPlace, fatherName, motherName, nationality) { }حالا هر شخص یه کد ملی داره. برای جنریت کردن کد ملی یه فانکشن واسه جنریت کردن عدد رندوم بین دو تا عدد مینویسیم و بعد بین عدد 100000000 و 9999999999 عدد رندوم جنریت میکنیم.(کد ملی ده رقمی هست). به این شکل:function generateRandomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
function born(name, lastName, birthPlace, fatherName, motherName, nationality) { 
const nationalCode = const nationalCode = generateRandomNumber(1000000000, 9999999999);
}حالا باید ویژگی های هر فرد رو ببینیم چجوریه.یک فرد میتونه اسم و اسم فامیلیشو عوض کنه، ولی نمیتونه اون ها رو حذف کنه. همچنین پدر و مادر یک فرد هم میتونن اسمشون رو تغییر بدن ولی نمیتونن اسمشون رو حذف کنن. ملیت یک فرد، کد ملی یک فرد و محل تولد یک فرد غیر قابل تغییر و غیر قابل حذف هستن. محل تولد یک فرد هم برای یک کشور خارجی مهم نیست. سن یک فرد قابل تغییر هست ولی غیر قابل حذف هست. همچنین ما یک ویژگی برای دریافت کل اطلاعات شناسنامه و تغییر  اطلاعات شناسنامه قرار میدیم.حالا بریم سراغ ساخت شناسنامه.چون پراپرتی های شناسنامه زیاد هستن، ما میایم از متد Object.defineProperties استفاده برای کانفیگ پراپرتی هامون. این متد برای تعریف گروهی از پراپرتی ها در یک آبجکت هست. این متد دو تا آرگیومنت میگیره. آرگیومنت اول آبجکت تارگت هست و آرگیومنت دوم آبجکتی از پراپرتی ها هست که میخوایم به آبجکت تارگت اضافه بشن. مقدار هر پراپرتی توی آبجکت پراپرتی ها، یک آبجکت هست که شما میتونید کانفیگ های مورد نظرتون برای اون پراپرتی رو توی آبجکتی که انتساب میدید به اون پراپرتی بنویسید. مثال:const object1 = {};
Object.defineProperties(object1, {
  property1: {
  //کانفیگ ها
  value: 42,
  writable: true
 },
  property2: {}
});حالا ما پراپرتی های آبجکت person رو به این صورت کانفیگ میکنیم و ریترن میکنیم:function born(name, lastName, birthPlace, fatherName, motherName, nationality) {
const nationalCode = generateRandomNumber(1000000000, 9999999999);
const age = 0;
const person = {};
Object.defineProperties(person, {
name: {
value: name,
configurable: false,
writable: true,
enumerable: true,
},
lastName: {
value: lastName,
configurable: false,
writable: true,
enumerable: true,
},
birthPlace: {
value: birthPlace,
configurable: false,
enumerable: false,
},
fatherName: {
value: fatherName,
configurable: false,
writable: true,
enumerable: true
},
motherName: {
value: motherName,
configurable: false,
writable: true,
enumerable: true,
},
nationality: {
value: nationality,
configurable: false,
enumerable: true,
},
nationalCode: {
value: nationalCode,
configurable: false,
enumerable: true,
},
age: {
value: age,
configurable: false,
writable: true,
enumerable: true,
},
getPrintedInfos: {
get: function () {
let infos = ``;
for (const key in this) {
infos += ` | ${key}: ${this[key]} | `;
}
return infos;
},
configurable: false,
enumerable: false,
},
setInfo: {
set: function (v) {
const splitedV = v.split(&amp;quot,&amp;quot);
this[splitedV[0]] = splitedV[1];
},
enumerable: false,
configurable: false
},
});
return person;
}خب این هم از شناسنامه.این هم از این مقاله. امیدوارم کلی چیز یاد گرفته باشید و از این مقاله خوشتون اومده باشه.اگه دوست داشتید لایک کنید مقاله مو. اگه دوست داشتید دنبال کنید من رو. اگه دوست داشتید یه کامنت مثبت و یا انتقاد منطقی بزارید واسم. خلاصه هرکاری دوست داشتید توی زندگیتون انجام بدید؛ هرکاری که به کسی آسیب نزنه و یا غمگینش نکنه :)</description>
                <category>null</category>
                <author>null</author>
                <pubDate>Wed, 23 Nov 2022 00:49:28 +0330</pubDate>
            </item>
                    <item>
                <title>آموزش ریکت(قسمت پنجم)</title>
                <link>https://virgool.io/@undefined/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-%D8%B1%DB%8C%DA%A9%D8%AA%D9%82%D8%B3%D9%85%D8%AA-%D9%BE%D9%86%D8%AC%D9%85-xx5nijsqikzb</link>
                <description>سلام. امیدوارم حالتون خوب باشه.توی این قسمت از آموزش ریکت، قراره بریم سراغ ایونت ها. اگر قسمت قبلی این سری مقاله ها رو نخوندید، پیشنهاد میکنم حتما بخونید.توی 4 قسمت قبل از این آموزش، هیچ حرفی راجع به ایونت ها نزدم. اینکه چجوری ایونت ست میکنیم و چیزای دیگه. به احتمال خیلی زیاد اگه الان دارید این آموزش رو میخونید، با ایونت ها و نحوه اضافه کردن ایونت ها توی جاوا اسکریپت خام، آشنایی دارید. میدونید که برای اضافه کردن ایونت به المنت های دام از طریق جاوا اسکریپت باید از متد addEventListener استفاده کنید و توی این متد نوع ایونت و کالبک فانکشن رو به عنوان آرگومان بهش بدید. باید بگم که توی ریکت، به کلی با اضافه کردن ایونت به دام خداحافظی کنید. چون دیگه ما با این روش به المنتای دام ایونت اضافه نمیکنیم. ما میخوایم به المنتای ریکتی ایونت اضافه کنیم. اضافه کردن ایونت به المنتای ریکتی با اضافه کردن ایونت به المنتای دام، سه تا تفاوت داره:1- توی ریکت، ایونت ها با حروف کمل کیس اضافه میشن به المنتای ریکتی. یعنی حرف کلمه اول کوچیک و حرف کلمه دوم به بعد بزرگ نوشته میشه. ولی توی کد های اچ تی ام ال، مثلا میخواستیم ایونت کلیک به یه دکمه اضافه کنیم، باید اسم ایونت رو مینوشتیم  ولی توی ریکت باید بنویسیم 2- توی ریکت، به جای اینکه به ایونتمون به صورت استرینگ یه فانکشن بدیم، خود فانکشن رو میدیم. توی اچ تی ام ال باید به یه تگ باتن اینجوری فانکشن رو به ایونت میدادیم:&lt;button =&quot;hello()&quot;&gt;say hello&lt;/button&gt;ولی توی ریکت باید اینجوری فانکشن رو به ایونت بدیم:&lt;button ={hello}&gt;say hello&lt;/button&gt;روش سوم: یه چیز دیگه که بین ست کردن ایونت توی المنتای ریکتی با المنتای اچ تی ام ال فرق هست اینه که توی اچ تی ام ال برای جلوگیری از عملکرد دیفالت یه المنت، میتونید مقدار فالس ریترن کنید. ولی توی ریکت باید حتما از e.preventDefault() استفاده کنید برای جلوگیری از اجرای عملکرد دیفالت یه المنت. به این شکل: function Form() {
  function handleSubmit(e) {
    e.preventDefault();    console.log(&#039;You clicked submit.&#039;);
  }

  return (
    &lt;form ={handleSubmit}&gt;
      &lt;button type=&amp;quotsubmit&amp;quot&gt;Submit&lt;/button&gt;
    &lt;/form&gt;
  );
}احتمالا میتونید حدس بزنید اینجا e به چه معناست. در اینجا ریکت یه سری اطلاعات راجع به المنت واسه ایونت هندلر ارسال میکنه که یه نمونش که اینجا هست همین فانکشن preventDefault هست. دقت کنید که اطلاعاتی که ریکت به عنوان آرگومان واسمون میفرسته یکمی متفاوت هستن که به اونا در اینجا نمیپردازم.همونجور که گفتم توی ریکت دیگه واقعا نیازی به استفاده از متد اد ایونت لیسنر نیست و فقط کافیه ایونتتون رو توی تگ جی اس ایکسی وارد کنید. مشابه کد های بالا. و اینکه هر ایونت ریکتی هم با on شروع میشن. مثلا .توی ریکت توی کلاس کامپوننت ها، یه الگوی پر استفاده برای تعریف ایونت هندلر ها، تعریف کردن اون ها به عنوان متدی از کلاس هست و بعد پاس دادن اون به ایونت. البته میتونید متدتون رو توی همون ایونت هم بنویسید. مشکلی پیش نمیاد. ولی یه چیزی نیازه که خیلی بهش توجه داشته باشید.وقتی شما میخواید ایونت هندلرتون که توی کلاستون هست رو بفرستید به ایونت توی جی اس ایکس، حتما باید اون رو bind کنید به کلاستون. در غیر این صورت this توی متدتون undefind میشه و عملیات انجام نمیشه. البته در صورتی که متدتون با یه عضو از کلاستون کار داشته باشه مثل استیت یا یه پراپرتی از کلاستون و... .به سه روش میتونید توی کلاس کامپوننتا ایونت هندلرتون رو به کلاستون بایند کنید:روش اول: میتونید بعد از تعریف متدتون، بایند شده متدتون رو ذخیره کنید. به این شکل:روش دوم: روش سوم:میتونید متدتون روی توی کالبک ساخته شده توی ایونت هم صدا بزنید. البته با این روش باعث میشید که با هر بار ری رندر شدن کامپوننتتون، اون کالبک دوباره ساخته بشه. و اگر اون کالبک رو به عنوان پراپ به کامپوننتای دیگه بفرستید میتونه باعث ری رندرینگ اضافی اون کامپوننتا بشه که واسه پرفورمنس مضر هست. پس یا از روش اول استفاده کنید، یا از روش دوم.اضافه کردن آرگومان به ایونت هندلربعضی موقه ها ممکنه بخواید آرگومان اضافه به ایونت هندلرتون بفرستید. برای اینکه آرگومان اضافی به ایونت هندلر بفرستید، کافیه بعد از اولین آرگومان متد bind که اسکوپ رو مشخص میکنه، آرگومانتونو بفرستید. البته اگه میخواید آبجکت اطلاعات المنتو هم دریافت کنید حتما واسه اون هم آرگومان تعریف کنید. و اینکه ریکت آبجکت مشخصات المنت رو همیشه به عنوان آخرین آرگومان به متدتون میفرسته اگر از روش کالبک استفاده نکنید. به این شکل:اگر از نوع کالبک استفاده میکنید، میتونید آبجکت اطلاعات رو به هر آرگومانی که دوست داشتید به متدتون پاس بدید.خب. امیدوارم ازین قسمت خوشتون اومده باشه. اگر با متد bind آشنا نیستید، حتما راجع بهش سرچ کنید. منتظر قسمت بعدی این سری از مقاله ها باشید.اگه دوست داشتید لایک کنید مقاله مو. اگه دوست داشتید دنبال کنید من رو. اگه دوست داشتید یه کامنت مثبت و یا انتقاد منطقی بزارید واسم. خلاصه هرکاری دوست داشتید توی زندگیتون انجام بدید؛ هرکاری که به کسی آسیب نزنه و یا غمگینش نکنه :)</description>
                <category>null</category>
                <author>null</author>
                <pubDate>Mon, 07 Feb 2022 01:35:32 +0330</pubDate>
            </item>
                    <item>
                <title>آموزش ریکت(قسمت چهارم)</title>
                <link>https://virgool.io/@undefined/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-%D8%B1%DB%8C%DA%A9%D8%AA%D9%82%D8%B3%D9%85%D8%AA-%DA%86%D9%87%D8%A7%D8%B1%D9%85-wz8mxsdf2j6i</link>
                <description>سلام. به قسمت چهارم از آموزش ریکت خوش اومدید. توی این قسمت با هم state ها و متد های lifecycle رو توی کلاس کامپوننت ها بررسی میکنیم. اگر قسمت های قبلی رو نخوندید، پیشنهاد میکنم حتما بخونید چون یه سری چیزاشون به هم دیگه مربوط هستن.توی قسمت دوم که در مورد رندرینگ المنت ها توی ریکت توضیحاتی دادم، یه مثال زدم واستون که مثالی از ساعت بود. این مثال:حالا میخوایم این مثال رو تبدیل کنیم به یه کامپوننت واقعی که قابل استفاده مجدد باشه و بتونیم n جا ازش استفاده کنیم. ازونجایی که فعلا به متد های لایف سایکل و استیت ها توی فانکشن کامپوننت ها نمیپردازم چون طبق داکیومنت فعلی ریکت دارم پیش میرم و به اون قسمت ها هم میرسیم، من بهتون پیشنهاد میکنم برای تمرین هم که شده، این فانکشن رو تبدیلش کنید به یه کلاس کامپوننت که طرز ساختش رو توی قسمت قبل توضیح دادم. اصلا نگران این نباشید که ساعت کار نمیکنه و به فکر راه انداختن ساعت نباشید. شما فقط این فانکشن رو به یه کلاس کامپوننت تبدیلش کنید که یو آی داشته باشه و کد های منطقی ای نداشته باشه.خب. موفق بودید؟ کد این کامپوننت رو میتونید ببینید:این کلاس کامپوننت، غیر قابل تغییر هست. یعنی وقتی به دام افزوده شد، تغییر نمیکنه و یه ساعت ثابت شما میبینید. ما این رو نمیخوایم. ما میخوایم هر ثانیه، کامپوننتمون آپدیت باشه. برای این کار، شما باید از چیزی به اسم استیت استفاده کنید. استیت، آبجکتی از چیز هایی هستند که ما میخوایم با تغییر کردن اون ها، کامپوننتمون آپدیت بشه. توی این کامپوننت، ما میخوایم ساعت رو آپدیت کنیم. پس ساعتمون رو باید بزاریم توی استیت.چجوری توی کلاس کامپوننت ها از استیت استفاده کنیم؟برای استفاده از استیت شما باید متد کانستراکتور که یه آرگومان به نام پراپس داره به بدنه کلاستون اضافه کنید. توی بدنه متد کانستراکتور باید از متد سوپر استفاده کنید و آرگومان متد کانستراکتور رو بهش پاس بدید. بعدش باید با استفاده از this.state یه آبجکت که مقادیر مورد نیازتون که در صورت تغییر اون ها، کامپوننت آپدیت میشه رو بهش انتساب بدید. در اینجا چون ما میخوایم ساعت رو توی استیت ذخیره کنیم، دیگه نیازی نیست که توی جی اس ایکس یه اینستنس دیگه از کلاس Date بسازیم. میایم از مقدار ذخیره شده توی استیتمون استفاده میکنیم. چون اون مقدار هر بار آپدیت میشه. برای دسترسی به یه مقدار توی استیت هم باید از کلیدواژه this و سپس state و پراپرتی مورد نظر استفاده کنید. به این شکل:خب ما الان قدم اول ساخت ساعتمون رو برداشتیم. قدم دوم چی هست؟ تغییر استیت!ما میخوایم وقتی ساعتمون به دام افزوده شد، متد setInterval رو اجرا کنیم و بعد هر یک ثانیه مقدار استیتمون رو آپدیت کنیم. کار آپدیت استیتمون رو میسپریم به یه متد به نام tick. پس بعد از هر یک ثانیه، متد tick باید فراخونی شه. حالا چجوری کاری کنیم که وقتی کامپوننت لود شد، متد ست اینتروال فراخوانی بشه؟ با استفاده از متد های لایف سایکل!متد های لایف سایکل چی هستن؟توی ریکت، یه سری متد ها هستن(چه توی کلاس کامپوننت چه توی فانکشن کامپوننت) که مربوط به چرخه زندگی کامپوننت هستن. مثلا ما میخوایم وقتی کامپوننت واسه اولین بار به دام افزوده شد، یه سری کارا انجام بدیم. فقط واسه واسه اولین بار که کامپوننت به دام افزوده شد! برای اینکار متد وجود داره. یا مثلا ما میخوایم بعد از هر بار آپدیت شدن کامپوننتمون، یه کاری انجام بدیم. برای این هم متدی وجود داره. یا ما میخوایم اجازه آپدیت شدن یه کامپوننت رو صادر کنیم. برای اینکار هم متد وجود داره!! به این متد ها که مربوط چرخه عمر کامپوننت هستن، میگن متد های لایف سایکل. توی این مقاله با دو تا از متد های لایف سایکل آشنا میشید.چجوری وقتی کامپوننتمون به دام افزوده شد، ساعت رو راه بندازیم؟دیدید که ساعت ما کار نمیکرد. حالا میخوایم با استفاده از متد های لایف سایکل ساعتمون رو راه بندازیم. میخوایم وقتی کامپوننتمون برای اولین بار به دام افزوده شد، ساعت شروع به کار کنه. به این کار میگن mounting. برای اینکار، ما باید از متد componentDidMount استفاده کنیم. اصلا هم چیز عجیب غریبی نیست کار با این متد. خب چجوری از این متد استفاده کنیم؟ توی بدنه کلاس کامپوننتمون این متد رو اضافه میکنیم و توی بدنه این متد، ساعتمون رو با متد setInterval راه میندازیم که هر یک ثانیه، متد tick رو فراخوانی میکنه و متد tick هم استیتمونو آپدیت میکنه. به این شکل:خب. اول با متد tick شروع میکنیم. این متد، همونطور که گفتم، استیت ما رو آپدیت میکنه. شما برای آپدیت کردن استیت باید از متد this.setState استفاده کنید. این متد دو تا آرگومان دریافت میکنه که ما فقط با آرگومان اولش کار داریم در اینجا. برای آپدیت کردن پراپرتی Date توی آبجکتی که به استیتمون دادیم، باید یه آبجکت به عنوان آرگومان اول به متد this.setState بدیم. توی این آبجکت، اسم پراپرتی ای که میخوایم توی استیت آپدیت بشه رو مینویسیم و مقدار جدید رو بهش انتساب میدیم که در اینجا پراپرتی Date رو ما میخوایم آپدیت کنیم. با انجام دادن اینکار، ما استیتمون رو آپدیت میکنیم و آپدیت شدن استیت باعث آپدیت شدن کامپوننتمون میشه. یه نکته که نیازه بهش توجه کنید اینه که توی آبجکتی که به this.setState میدید، فقط پراپرتی هایی که میخواین آپدیت کنین رو بنویسین و مقدار جدید رو بهشون انتساب بدین. مثلا اگر استیت کامپوننتتون سه تا پراپرتی داشت به نام های name، age و city و شما میخواستید فقط name و age رو آپدیت کنید، فقط این دو تا پراپرتی ای که میخواین آپدیت کنین رو توی آبچکتی که به عنوان آرگومان اول this.setState  میدید بنویسید و مقدار جدید بهش انتساب بدید. نیازی نیست city رو بنویسید. چون ریکت خودش مقادیر آپدیت شده رو با استیت شما ترکیب میکنه و پراپرتی city آبجکت توی استیتتون از بین نمیره. پس نگران این موضوع نباشید.خب. ما الان منطق آپدیت شدن ساعتمون رو هم نوشتیم. بریم سراغ منطق شروع به کار کردن ساعتمون.گفتیم ما میخوایم وقتی کامپوننت ساعتمون به دام افزوده شد، ست اینتروال شروع به کار کنه. پس باید چیکار کنیم؟ باید از متد componentDidMount استفاده کنیم. همونطور که قبل تر گفتم، این متد به محض اینکه کامپوننت به دام افزوده شد، اجرا میشه. خب ما توی componentDidMount توی کد بالا، ست اینتروال رو استارت زدیم. متد ست اینتروال یه آی دی مختص به خودش رو برمیگردونه که ما میتونیم از اون بعدا برای متوقف کردن ست اینتروال استفاده کنیم. به همین دلیل اون رو توی timerID توی کلاسمون ذخیره میکنیم. ازونجایی که this.state معنی خاصی داره و this.props توسط خود ریکت به کلاس افزوده شده، ما میتونیم بدون نگرانی از بین رفتن داده هامون، توی کلاسمون داده هامونو ذخیره کنیم. مثل this.timerID.خب. الان اگه این کامپوننت رو به دام اضافه کنید، میبینید که ساعت شما به درستی کار میکنه :)ولی یه چیز دیگه مونده. ممکنه ما بخوایم کامپوننتمون رو بعد از اینکه مثلا کاربر روی یه دکمه کلیک کرد، از روی دام حذف کنیم. آیا این درسته که ما کامپوننت رو حذف کنیم ولی ست اینتروال همینجوری واسه خودش کار کنه؟ یا اصلا فرض کنید با کلیک کردن روی اون دکمه، اگه ساعت روی دام بود اون ساعت حذف میشه. اگه ساعت روی دام نبود، اون ساعت اضافه میشه به دام. خب مثلا الان کاربر 20 بار روی دکمه کلیک کنه. 10 بار متد ست اینتروال اجرا میشه!!! حتی وقتی کامپوننت از دام حذف شد، اون ست اینتروالا حذف نمیشن! خب این اصلا برای سرعت بخشیدن به اپمون خوب نیست. راه حل چیه؟ استفاده از متد لایف سایکل componentWillUnmount.این متد چیکار میکنه؟ این متد قبل از اینکه ریکت، کامپوننت مورد نظر رو از دام حذف کنه، ریکت اول این متد رو اجرا میکنه و بعدش کامپوننت رو از دام حذف میکنه. ما دقیقا به این متد نیاز داریم. ما میخوایم وقتی کامپوننت میخواد از دام حذف بشه، اون ست اینتروال رو حذف کنیم. پس باید به این شکل عمل کنیم:در اینجا ما توی متد componentWillUnmount با استفاده از متد clearInterval ست اینتروال ساعتمون با آی دی ای که ازش ذخیره کردیم رو پاک کردیم. الان ما یه ساعت کاملا استاندارد و با پرفورمنس بالا و قابل استفاده داریم. و میتونید هر چقدر که دوست داشتید ازین ساعت جا های مختلف برنامه تون استفاده کنید بدون نگرانی از اینکه اگه یکیشون از دام حذف شه، ست اینتروالش باقی میمونه.کمی بیشتر راجع به استیتدو تا چیز هست که شما باید توی ریکت راجع به استیت توجه داشته باشید:1- استیت هاتون رو به طور مستقیم تغییر ندیدتوی ریکت، شما به هیچ عنوان نباید مقادیر استیت رو مستقیما تغییر بدید. همیشه برای تغییر دادن استیت باید از متد this.setState توی کلاس کامپوننتا استفاده کنید. چون تغییر دادن مستقیم استیت، باعث رفرش شدن کامپوننت شما نمیشه. برای مثال:2- آپدیت شدن استیت و پراپس اسینکرونس(نا همگام) هستاگر راجع به مفهوم همگام و ناهمگامی نمیدونید، پیشنهاد میکنم حتما به این مقاله که من نوشتم سر بزنید. چون اگه مفوم ناهمگامی رو ندونید این قسمت رو خیلی سخت متوجه میشید. توی اون مقاله خیلی کامل و با دلیل واستون توضیح دادم این موضوع رو. خب. اینجا واستون توضیح میدم این موضوع رو. اول با اسینکرونس بودن آپدیت شدن استیت ها شروع میکنم. ببینید، متد های ست استیت توی کلاس کامپوننت ها جمع آوری میشن و سپس همشون به یه آپدیت برای کامپوننت تبدیل میشن. شاید بپرسید خب چرا؟ چون این به پرفورمنس برنامه مون کمک زیادی میکنه. خب مشکل از کجا شروع میشه؟ از اینجا که هر ست استیت فقط و فقط به مقدار حال حاضر کامپوننت دسترسی داره. یعنی اینجوری نیست که با دستور ست استیت اول که استیتو آپدیت کردیم، استیت آپدیت شده برای بقیه ست استیت ها هم در دسترس باشه! بزارید با یه مثال واستون روشن کنم موضوع رو.ما یه کامپوننت شمارنده داریم. این کامپوننت میخواد با هر بار کلیک کاربر روی دکمه +، با استفاده از 3 بار فراخوانی کردن ست استیت و افزایش عدد یک به مقدار حال حاضر استیت، استیت شمارنده رو 3 تا افزایش بده. به این شکل:ولی این کد در کمال تعجب مشکل داره و اگه کاربر روی دکمه + کلیک کنه، فقط یه دونه به مقدار شمارنده توی استیت اضافه میشه! چرا این اتفاق میوفته؟ چون همونطور که گفتم ست استیت ها جمع آوری میشن و در آخر تبدیل به یک آپدیت واسه کامپوننت میشن به جای سه تا آپدیت و هر ست استیت به مقدار استیت زمان شروع عملیات توی کامپوننتش دسترسی داره نه به مقدار آپدیت شده توسط ست استیت قبلی! به ترتیب واستون توضیح میدم.اینجا، وقتی متد increment صدا زده شد، ست استیت ها اول جمع آوری میشن.  بعدش ست استیت اولی انجام میشه. شمارنده یکی افزایش پیدا میکنه. ست استیت دوم ازونجایی که به مقدار استیت در زمان فراخوانی increment که 0 هست فقط دسترسی داره نه به مقدار به روز شده که 1 هست، میاد و به 0 عدد 1 رو اضافه میکنه. ست استیت سوم هم همینطور. در آخر این آبجکتا با هم ترکیب میشن(قبل تر اشاره کردم) و یکیشون اعمال میشه چون همشون مثل همن. بعدش که مقدار استیت اصلی آپدیت شد، ریکت متد رندر کامپوننتمون رو صدا میزنه! الان فکر میکنم متوجه شده باشید که چرا این اتفاق میوفته. خب. راه حل چی هست؟ چجوری میتونیم به استیت آپدیت شده دست پیدا کنیم توی هر ست استیت که بتونیم واقعا شمارنده توی استیت رو 3 تا افزایش بدیم؟ با استفاده از نوع دوم متد ست استیت!نوع دوم متد ست استیت اصلا چیز عجیب غریبی نیست. فقط کافیه یه کالبک فانکشن با یه آرگومان به متد ست استیت پاس بدیم و مقداری که میخوایم آپدیت کنیم رو ریترن کنیم از اون کالبک. و به جای اینکه از استیت اصلی خود کامپوننتمون استفاده کنیم، از اون آرگومان کالبک استفاده میکنیم چون مقدار به روز استیت رو نشونمون میده. حالا به راحتی میتونیم با استفاده از سه بار فراخوانی ست استیت، به مقدار شمارنده مون سه تا اضافه کنیم. البته میتونیم اولین ست استیت رو به صورت معمولی فراخوانی کنیم چون در هر صورت به مقدار مورد نیازش از استیت خود کامپوننت دسترسی داره. به این شکل میشه کار های بالا رو انجام داد:الان به شمارنده استیت اصلی ما 3 تا اضافه میشه. چون آرگومان اول کالبک متد ست استیت، واسه ما استیت به روز شده رو میاره که همونطور که گفتم میشه ست استیت اول رو به شکل معمولی هم نوشت چون در هر صورت مقدار شمارنده استیت جدیدش همون مقداریه که موقع استفاده از کامپوننت بوده. ولی ست استیت های بعدی رو باید حتما از نوع دوم استفاده کرد به دلیلی که بالاتر توضیح دادم. در اینجا شما میتونید با استفاده از ابزار بریک پوینت بروزر کروم، مشاهده کنید که اول همه ست استیت ها جمع آوری میشن و سپس کالبک هاشون صدا زده میشن.خب. الان به احتمال زیاد منظور از اسینکرونس بودن استیت ها رو درک کردید توی ریکت. بریم سراغ درک اسینکرونس بودن آپدیت پراپس توی ریکت.اگر قسمت های قبلی این سری رو خونده باشید، میدونید که پراپس توی کامپوننت های ریکتی غیر قابل تغییر هستن. پس منظور از اسینکرونوس بودن پراپس چی هست؟ما میدونیم که هر نوع پراپی میتونیم به کامپوننتای فرزندمون بدیم. اون پراپ میخواد نوعش فانکشن باشه، آبجکت باشه، استرینگ باشه، هر چیزی باشه.فرض کنید ما میخوایم عددی که به مقدار counter توی استیت اضافه میشه رو از کاربر بگیریم. و میخوایم بعد از اضافه شدن اولین مقدار به شمارنده استیتمون، یه دونه به عدد وارد شده توسط کاربر اضافه بشه. اینپوتمون هم یه کامپوننت جدا داره و مقدار اینپوت توی استیتش ذخیره شده. باید چیکار کنیم اینجا؟ باید مقدار استیت رو از طریق پراپ به کامپوننت ارسال کنیم و بعد متد ست استیت رو هم از طریق پراپ ارسال کنیم که بتونیم مقدار استیت کامپوننت پدر رو عوض کنیم. تا اینجا همه چی خوب هست.کد ها رو کامل نمیزارم چون نمیخوام ذهنتنو سر یه چیزایی درگیر کنم. و اینکه این فقط یه شبیه سازی ازینکه مقدار از کاربر گرفته میشهولی وقتی که این کد رو اجرا میکنیم بار اول که روی + کلیک میکنیم متوجه میشید که 3 تا به شمارنده استیت  اضافه شده به جای 5 تا! ولی به چه دلیل؟ چون ست استیت به پراپس حال حاضر خودش فقط دسترسی داره نه به پراپس جدیدش! راه حل چی هست؟ یادتونه گفتم متد ست استیت نوع دومی داره که کالبک فانکشن میگیره و آرگومان اول اون کالبک فانکشن، مربوط به استیت به روز شده هست؟ باید بگم که این کالبک آرگومان دوم هم داره. آرگومان دومش مخصوص پراپس به روز شده هست. ما میتونیم کد بالا رو به کد پایین تبدیل کنیم:خب. اینجا ما فکر میکنیم همه چی درست هست تا زمانی که برنامه رو تست میکنیم. اینجاست که میفهمیم به جای اینکه مقدار شمارنده توی استیتمون 5 تا بره جلو، 6 تا میره جلو. دلیلش چی هست؟ دلیلش این هست که وقتی همه ست استیت ها جمع آوری شدن، چون یه ست استیت مال یه کامپوننت دیگه هست و هیچ ربطی به کامپوننت counter نداره، ریکت میاد و اول استیت توی کامپوننت پدر رو آپدیت میکنه و باعث میشه کامپوننت پدر ری رندر بشه. بعدش میره و ست استیتای کامپوننت Counter رو تبدیل به یه آپدیت میکنه و استیت اصلی رو آپدیت میکنه. این باعث میشه که وقتی استیت کامپوننت پدر به روز شد، توی پراپس جدید همه ست استیتای مربوط به کامپوننت counter مقدار amount برابر با 2 بشه و سه تا دو به استیت اضافه بشه و در نتیجه به استیت اصلی 6 تا اضافه بشه. پس باید چیکار کنیم؟ از همون نکته ای که گفتم همه ست استیتا به پراپس حال حاضر خودشون توی زمان شروع عملیات دسترسی دارن باید استفاده کنیم. چون کار ست استیتای مربوط به کامپوننت خودمون که تموم نشده. فقط مقدار استیت کامپوننت پدر به روز شده و باعث نمیشه که مقدار پراپسی که ست استیتای خودمون داشتن تغییر کنه چون در زمان شروع، پراپ amount ما 1 بوده.پس خیلی راحت میایم و به پراپ فعلی خودمون اشاره میکنیم. به این شکل:الان دیگه اگه کاربر بار اول روی + کلیک کرد، 5 تا به شمارنده مون اضافه میشه. بارای بعدی 6 تا. چون بعد از بار اول استیت کامپوننت پدر تغییر میکنه دیگه.خب این هم از این. امیدوارم اینجا رو متوجه شده باشید. سعی کردم خیلی ساده و با مثال توضیح بدم واستون.توی ریکت یه مفهومی هست که بهش میگن (Data down Action up). میخوایم این مفهوم رو با هم بررسی کنیم. اول با Data down شروع میکنم. ببینید، ما توی ریکت، فقط به کامپوننت های فرزند میتونیم اطلاعات رو بفرستیم. منظور از Data down این هست. ساختار دام رو یادتون هست؟ ساختارش یه حالت درختی ای از آبجکت ها هست که ریشه این درخت تگ html هست. توی ریکت هم یه همچین ساختاری داریم منتهی از نوع کامپوننتی. اگه یادتون باشه توی مقاله های قبلی گفتم که توی اپ های ریکتی، معمولا ریکت دولوپر ها میان و تمام ساختارشون رو میزارن توی یه کامپوننت اصلی به اسم App یا هرچیز دیگه. این کامپوننت نقش پدر برای کامپوننتای بدنه ش داره. دقیقا مثل تگ html. حالا کامپوننت App، میتونه به همه فرزنداش دیتا بفرسته از طریق پراپس. کامپوننت های فرزند میتونن همون دیتا ها رو بفرستن برای کامپوننتای فرزندشون. دوباره اون کامپوننتا هم همینکار رو میتونن بکنن. به این درخت میگن UI tree. و این شد از مفهوم Data down و یه سری توضیحات دیگه.حالا Action up چیه؟ توی ریکت، کامپوننتا، به هم دیگه دسترسی ندارن. و این یعنی کامپوننتا نمیتونن متد های کامپوننتای دیگه رو خودشون اجرا کنن. اینجا مفهوم action up میاد وسط. وقتی ما فانکشنی رو از طریق پراپس میفرستیم به یه کامپوننت زیر مجموعه، اگر اون رو اجراش کنیم، اون فانکشن باید از کامپوننتایی که ازش از طریق پراپس اومده، بره بالا تا برسه به اون کامپوننتی که توش تعریف شده. اونجا اجرا میشه و اگر استیتی چیزی تغییر کرد یا نکرد هم خودش هم اون مقدار دوباره از طریق پراپس فرستاده میشن پایین. برای مثال:قبل تر که داشتم مفهوم اسینکرونس بودن آپدیت شدن پراپس و ست استیت ها رو توضیح میدادم، اگر یادتون باشه من از کامپوننت App، ست استیت و مقدار counter رو فرستادم به کامپوننت فرزندش که Counter بود. توی متد increment اون رو صداش زدم. اینجا چه اتفاقی میوفته؟ دقیقا همین بحث data down action up میاد وسط. دیتا ها که یکی فانکشنمون بود و یکی مقدار شمارنده مون بود فرستاده میشن به کامپوننت فرزند و بعدش با صدا زدن متد increment، متد ست استیت فرستاده میشه به کامپوننت App. اونجا اجرا میشه و بعدش که استیت تغییر پیدا کرد دیتا ها که خود ست استیت و مقدار شمارنده هست، دوباره فرستاده میشن پایین.این تصویر میتونه توی فهم data down action up بهتون کمک کنه.نکته: کامپوننت ها همشون از هم دیگه جدا هستن و به هم دیگه بستگی ندارن! یعنی مثلا شما شما کامپوننت ساعتی که توی این قسمت ساختیم رو هر چند بار که خواستید میتونید ازشون استفاده کنید و به بدنه کامپوننت پدرشون وصل کنید. اصلا این ها بهم دیگه مربوط نیستن و کارشون جدا از هم هست.خب. این هم از این قسمت. امیدوارم خوشتون اومده باشه از این قسمت و کلی چیز یاد گرفته باشید.اگه دوست داشتید لایک کنید مقاله مو. اگه دوست داشتید دنبال کنید من رو. اگه دوست داشتید یه کامنت مثبت و یا انتقاد منطقی بزارید واسم. خلاصه هرکاری دوست داشتید توی زندگیتون انجام بدید؛ هرکاری که به کسی آسیب نزنه و یا غمگینش نکنه :) </description>
                <category>null</category>
                <author>null</author>
                <pubDate>Sat, 05 Feb 2022 23:48:45 +0330</pubDate>
            </item>
                    <item>
                <title>آموزش ریکت(قسمت سوم)</title>
                <link>https://virgool.io/@undefined/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-%D8%B1%DB%8C%DA%A9%D8%AA%D9%82%D8%B3%D9%85%D8%AA-%D8%B3%D9%88%D9%85-mvvb5q5qfq6w</link>
                <description>سلام. توی این مقاله میخوام مفهوم کامپوننت و یک سری چیز ها رو راجع بهش به شما بگم. اگر قسمت قبل این مقاله رو نخوندید، پیشنهاد میدم بخونید.کامپوننت چیست؟کامپوننت ها، قسمت های قابل استفاده مجدد و تیکه هایی از یو آی اصلی وبسایت ما هستند. شما میتونید هر قسمت از سایتتون رو به کامپوننت های جداگونه تقسیم کنیم. این به شما کمک میکنه که برای طراحی هر کامپوننت، فقط به منطق و طراحی اون کامپوننت فکر کنید و پیچیدگی کار شما کمتر میشه. شما میتونید از کامپوننت ها، توی بدنه کامپوننت های دیگه استفاده کنید. مثل نوشتن تگ های تودر توی اچ تی ام ال. توی ریکت، دو نوع کامپوننت میشه ساخت. فانکشن کامپوننت و کلاس کامپوننت. سراغ ساخت هر کدوم از اینا هم میریم. اتریبیوت هایی که به یه کامپوننت اضافه میکنید در نهایت به یه آبجکت تبدیل میشن. به این آبجکت میگن props که مخفف properties هست که باعث میشن کامپوننت های ما قابل استفاده مجدد باشن و دیگه نیازی نیست که بیاید و متن های کامپوننت رو هارد کد(استاتیک نوشتن کد ها) کنید. به راحتی میتونید موقع استفاده از کامپوننت مورد نظرتون، مقادیری رو به عنوان پراپس به کامپوننتون بدید و توی کامپوننتتون از اون مقادیر استفاده کنید. تعریف پراپ برای یه کامپوننت دقیقا مثل تعریف اتریبیوت برای یه تگ جی اس ایکسی هست. به پراپ هاتون هر اسمی میتونید بدید(البته نه هر اسمی. با توجه به قوانین جاوا اسکریپت میتونید هر اسمی بدید). یک مثال از کاربردی بودن کامپوننت ها واستون میزنم:شما میخواید قسمت نظرات برای صفحه محصولتون تهیه کنید. هر نظر با نظر دیگه متفاوت هست. اینجا شما باید بیاید و قسمت نظرات رو خودتون توی صفحه نظرات بسازید؟ نه. چون شما از اون نظرات میخواید جاهای دیگه سایتتون هم استفاده کنید. مثلا قسمت نظرات راجع به سایتتون. اگر اینکارو کنید شما باید کد های قسمت نظرات صفحه محصولتون رو کپی پیست کنید توی قسمت اصلی سایتتون. خب این عاقلانه نیست. پس شما باید خود باکس نظر که نظر کاربر توش نوشته شده، یه کامپوننت بسازید. حالا که اون کامپوننت رو ساختید، واسه اینکه اون کامپوننت رو قابل استفاده مجدد کنید(n بار توی بخش نظرات محصول با تکستای مختلف نمایشش بدید و n بار هم توی بخش اصلی سایتتون که نظرات کاربر ها راجع به سایتتون هست با تکستای مختلف نمایشش بدید) باید چیکار کنید؟ باید از پراپس استفاده کنید.پس تا الان به مفهوم کامپوننت پی بردید. بریم سراغ ساخت فانکشن کامپوننت و کلاس کامپوننت.ساخت فانکشن کامپوننتفانکشن کامپوننت ها، همون توابع جاوا اسکریپتی هستن و چیز عجیب غریبی نیست ساختنشون. همه فانکشن کامپوننت ها، کد های جی اس ایکس بر میگردونن. کد های جی اس ایکس مربوط به خودشون.بریم کامپوننت کامنت رو بسازیم. خب کامپوننت کامنت چه چیزی رو نمایش میده؟ تکست کامنت، تاریخ کامنت و اسم کسی که کامنت گزاشته.برای ساخت کامپوننت کامنت، اینکار رو توی فایل index.js انجام بدید:به همین راحتی یه کامپوننت ساختم. اگر میخواید از پراپس استفاده کنید، یادتون باشه حتما پراپس رو به عنوان آرگومان به فانکشنتون اضافه کنید. و اینکه حتما هم نیازی نیست کامپوننت رو به شکل اررو فانکشن تعریف کنید. میتونید به شکل فانکشن معمولی تعریف کنید. حالا چجوری میشه از کامپوننت استفاده کرد و پراپ ها رو بهش ارسال کرد؟ اینجوری:الان ما به صفحه محصولاتمون سه تا کامنت با سه تا پراپ متفاوت اضافه کردیم. دقت کنید پراپ های یه کامپوننت، باید بر اساس اسم پراپی که ما توی یه کامپوننت نیاز داریم نامگزاری بشن. مثلا ما توی کامپوننت کامنت، به پراپ name نیاز داریم. پس باید موقع رندر کردن یو آی توی بدنه تگ باز یا خود تگ( کامپوننتایی که تگ فرزندی احتیاج ندارن رو میشه درجا بستشون. مثل &lt;/Comment&gt;) پراپ های مورد نیاز کامپوننت با مقادیر مورد نیازشون رو تعریف کنید. به همین راحتی میشه فانکشن کامپوننت ساخت!ساخت کلاس کامپوننتگفتم که ما دو نوع کامپوننت داریم. فانکشن کامپوننت و کلاس کامپوننت. فکر میکنم ریکت دولوپر ها تا قبل از اومدن ورژن 16.8.0 از کلاس کامپوننت ها استفاده میکردند چون فانکشن کامپوننت ها قابلیت های مهم که کلاس کامپوننت ها داشتن رو نداشتن. بعد از اومدن ورژن 16.8.0 ریکت، اون قابلیت ها توی فانکشن کامپوننت ها هم موجود شدن(اسم اون قابلیت رو نمیگم که ذهنتون درگیر نشه :)) و از اون موقع دیگه خیلی از ریکت دولوپر ها از فانکشن کامپوننت ها استفاده میکنن مگر در شرایط خاص که نیاز به کلاس کامپوننت دارند. به همین دلیل دونستن ساخت کلاس کامپوننت هم خیلی مهم هست. خب بریم سراغ ساخت کلاس کامپوننت ها.همونجور که از اسم این نوع کامپوننت معلوم هست، این کامپوننت ها در واقع کلاس هایی هستند که از یه کلاس خاص ارث بری میکنن. اسم اون کلاس خاص، Component هست. قبل از ساخت کلاس کامپوننت ها یادتون باشه که کلاس Component یا React رو از ماژول react ایمپورت کرده باشین چون میخوایم از کلاس Component ارث بری کنیم. کلاس کامپوننت عضوی از کلاس React هست که شما میتونید جداگونه هم ایمپورتش کنید.  کلاس کامپوننت ها رو اینجوری میسازن:میتونید از React.Component هم ارث بری کنید.خب ما در اینجا فانکشن کامپوننت کامنت رو به شکل کلاس ساختیم. توی کلاس کامپوننت ها برای اینکه کد جی اس ایکس رو برگردونید باید از متد render استفاده کنید و توی اون متد، تگ های جی اس ایکستون رو ریترن کنید. برای استفاده از پراپس باید از کلید واژه this و بعدش props و بعدش اسم پراپتون به اون پراپ دسترسی پیدا کنید و ازش استفاده کنید. به همین راحتی یه کلاس کامپوننت ساختید.یه نکته خیلی مهم برای ساخت کامپوننتبه گفته داکیومنت ریکت، شما باید برای ساخت کامپوننت ها، چه از نوع فانکشن چه از نوع کلاس، اسم اون ها رو با حرف بزرگ شروع کنید. در غیر این صورت ریکت با اون کامپوننت مثل تگ اچ تی ام ال رفتار خواهد کرد. میتونید تست هم بکنید. اسم کلاس کامپوننت کامنت رو از Comment به comment تغییر بدید. ریکت اون رو رندر نمیکنه توی دام و توی کنسول مرورگرتون بهتون ارور میده.استفاده از کامپوننت های تو در تو اول مقاله توی بخش کامپوننت چیست، بهتون گفتم که کامپوننت ها رو میشه توی کامپوننت های دیگه هم استفاده کرد. کار عجیب غریبی هم نیست. تگ جی اس ایکس رو چجوری به صورت تو در تو تعریف میکردیم؟ تعریف کامپوننت های تو در تو هم همینجوری هست. واستون یه مثال میزنم جلو تر.یه چیز کاربردی که هست اینه که توی برنامه های ریکت، معمولا یه کامپوننت اصلی وجود داره به اسم App. اسمشو هر چی دوست داشتید میتونید بزارید. این کامپوننت کل کامپوننت های شما رو در بر میگیره. از نویگیشن بار بگیر تا فوتر. و اینجوری شما توی کل برنامه تون فقط یک بار از ReactDOM.render استفاده میکنید که این خیلی عالی هست. چجوری اینکار رو انجام بدیم؟ اینطوری:الان ما از تمام کامپوننت های اصلیمون از جمله Footer و Header و Product توی کامپوننت اصلی برنامه مون که App هست استفاده کردیم. از کامپوننت Comment هم توی کامپوننت Product استفاده کردیم. پس دیدید که اصلا تعریف تو در توی کامپوننت ها سخت نیست.پراپس ها غیر قابل تغییر هستندتوی ریکت، شما نمیتونید پراپس کامپوننتتون حالا چه از نوع کلاس چه از نوع فانکشن، رو تغییر بدید. اگر این کار رو انجام بدید ارور دریافت خواهی کرد. توی ریکت، همه فانکشن ها pure یا خالص باید باشند. فانکشن های خالص به فانکشن هایی میگن که آرگومان های خودشونو تغییر نمیدن. فانکشن هایی که impure یا ناخالص هستن، آرگومان های خودشون رو دستکاری میکنن.تمرینچند تا عکس پروفایل پیدا کنید و توی فولدر public پروژه ریکتیتون ذخیره کنید. سپس یه کامپوننت به اسم Avatar بسازید توی فایل index.js که یه پراپ از نوع استرینگ دریافت کنه و اون پراپ، آدرس یکی از عکس های پروفایلی باشه که توی فولدر public ذخیره کردید. کامپوننت Avatar باید یه تگ img با سورسی که پراپتون هست، برگردونه. آدرس عکس ها رو جوری بدید که انگار از فایل index.html دارید عکستون رو لود میکنید. از این کامپوننت توی کامپوننت Comment استفاده کنید. و اینکه یادتون باشه اول پراپ رو به کامپوننت Comment ارسال کنید و بعد توی کامپوننت Comment، اون پراپ رو ارسال کنید به کامپوننت Avatar.با توجه به مفاهیمی که توی این مقاله و مقالات قبل گفتم، به احتمال زیاد میتونید این تمرین رو با موفقیت انجام بدید. توی مقاله بعدی جواب این تمرین رو میگم بهتون.خب به آخر مقاله رسیدیم. امیدوارم از این مقاله خوشتون اومده باشه و کلی چیز یاد گرفته باشید. منتظر قسمت بعدی باشید.اگه دوست داشتید لایک کنید مقاله مو. اگه دوست داشتید دنبال کنید من رو. اگه دوست داشتید یه کامنت مثبت و یا انتقاد منطقی بزارید واسم. خلاصه هرکاری دوست داشتید توی زندگیتون انجام بدید؛ هرکاری که به کسی آسیب نزنه و یا غمگینش نکنه :)</description>
                <category>null</category>
                <author>null</author>
                <pubDate>Fri, 04 Feb 2022 20:37:23 +0330</pubDate>
            </item>
                    <item>
                <title>آموزش ریکت(قسمت دوم)</title>
                <link>https://virgool.io/@undefined/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-%D8%B1%DB%8C%DA%A9%D8%AA%D9%82%D8%B3%D9%85%D8%AA-%D8%AF%D9%88%D9%85-hoz982jibwx0</link>
                <description>سلام. توی این قسمت، میخوام راجع به رندرنیگ المنتا توی ریکت حرف بزنم. اگه قسمت قبلیو نخوندین، پیشنهاد میدم حتما بخونید.همونطور که میدونید تگ های جی اس ایکسی توی ریکت، اسکلت وبسایت شما رو میسازن. توی ریکت، المنت هایی که تعریف میکنیم بر خلاف المنت های دام مرورگر، آبجکت هستن. توی قسمت قبل این رو گفتم. و ReactDOM.render با استفاده از اون آبجکت ها توی یو آی تغییرات ایجاد میکنن.توی ریکت، توی فایل index.html اگر دقت کنید یک تگ دیو با آی دی root وجود داره.(اگر پروژه ریکت که توی مقاله قبل آموزششو گفتم ساخته باشید) در واقع ریکت دام این دیو رو مدیریت میکنه. به دیو یا دیو هایی که توسط ریکت دام کنترل میشن، میگن المنت روت. میتونید آی دیشونو هم تغییر بدید. که البته موقع رندر کردن المنتا با استفاده از ReactDOM.render باید اون دیو رو با آی دی ای که انتخاب کردین واسش النتخاب کنید.توی اپ هایی که فقط با استفاده از ریکت ساخته شدن، معمولا یه دونه روت المنت وجود داره. ولی توی اپ هایی که فقط از یه سری امکانات ریکت استفاده میکنن و خودشون با چیزای دیگه مثلا اچ تی ام ال و سی اس اس و وانیلا جاوا اسکریپت توسعه داده شدن، ممکنه چندین روت المنت داشته باشن.برای اضافه کردن المنت های ساخته شدتون به روت المنت، همونطور که از قسمت قبلی یادتون هست باید از ReactDOM.render استفاده کنید.المنت های ریکت غیر قابل تغییر هستن. یعنی وقتی شما اون ها رو ساختید دیگه نمیتونید اتریبیوت ها و یا فرزاندای اون ها رو تغییر بدید. ولی ممکنه شما بخواید اپتون رو داینامیک بسازید. مثلا میخواید ساعت بسازید. خب باید تکست کانتنت تگتون که ساعت و تاریخ هست عوض بشه. اینجا در حال حاضر با دانشی که از ریکت و جاوا اسکریپت دارید، شما میتونید یه فانکشن بسازید و اونجا المنتایی که ساعتتون رو نمایش میده رو بسازید و سپس توی همون فانکشن، با استفاده از ReactDOM.render تگ رو مجدد اضافه کنید به روت المنتتون. بعدش با استفاده از setInterval هر یک ثانیه اون فانکشنتون رو صدا بزنید. همین مثال رو خود داکیومنت ریکت زده.میتونید نتیجه این کد رو ازین لینک ببینید. کد رو ویرایش هم میتونید کنید.یه چیزی که خیلی جالب هست اینه که ریکت دام، فقط تغییرات ضروری رو اعمال میکنه! یعنی چی؟ یعنی فقط اون تکستی که تغییر کرده! و این خیلی خفنه! مثلا توی کد بالا، فقط {new Date().toLocaleTimeString()} تغییر میکنه نه تگ دیگه ای یا تکست دیگه ای! خیلی جالبه. خود داکیومنت ریکت هم با یه گیف این رو ثابت کرده:توی این گیف اون تکستی که چشمک میزنه یعنی داره تغییر میکنه. همونطور که میبینید تکستای دیگه یا تگای دیگه تغییر نمیکنن و فقط اونچیزی که نیازه و باید آپدیت بشه که ساعت هست تغییر میکنه. این باعث میشه که خیلی از اشکالات ما در رابطه به تغییر دادن دام رفع بشه و اینکه کار کمتری هم انجام میده برناممون. چون کلا اضافه کردن و کلا کار با دام، کار نسبتا سنگینی هست و به این فکر کنید که اگه کل تگ اضافه شده به دام تغییر میکرد بهتر بود یا الان که فقط اون چیزی که نیازه تغییر میکنه؟ کدوم کار کمتری انجام میده؟ صددرصد آپدیت کردن چیزی که نیازه کار کمتری انجام میده.امیدوارم از این قسمت هم خوشتون اومده باشه. منتظر قسمت سوم باشید...اگه دوست داشتید لایک کنید مقاله مو. اگه دوست داشتید دنبال کنید من رو. اگه دوست داشتید یه کامنت مثبت و یا انتقاد منطقی بزارید واسم. خلاصه هرکاری دوست داشتید توی زندگیتون انجام بدید؛ هرکاری که به کسی آسیب نزنه و یا غمگینش نکنه :)</description>
                <category>null</category>
                <author>null</author>
                <pubDate>Thu, 03 Feb 2022 13:03:37 +0330</pubDate>
            </item>
                    <item>
                <title>آموزش ریکت(قسمت اول)</title>
                <link>https://virgool.io/@undefined/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-%D8%B1%DB%8C%DA%A9%D8%AA%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-ptw6mb6qidkv</link>
                <description>سلام. حدود دو سه ماهی هست که ریکت رو استارت زدم و اوایل با ویدیو جلو میرفتم. تا حدی جلو رفتم تا الان. الان میخوام برای عمیق شدن توی ریکت، برم سراغ خوندن داکیومنتش. مطمئنا میدونید که هیچ چیز مثل داکیومنت خوندن و پروژه زدن شما رو نمیتونه توی یه زبان، لایبرری یا فریموورک یا هر چیز دیگه ای عمیق کنه. و من هم برای اولین بار تصمیم گرفتم جزوه برداری کنم از اطلاعاتی که دستگیرم میشه :))با خودم گفتم چرا خلاصه چیز هایی که مینویسم رو جایی مثل ویرگول منتشر نکنم که کسایی که انگلیسیشون در حدی نیست که بتونن ویدیو انگلیسی ببینن یا داکیومنت بخونن یا اصلا حوصله داکیومنت خوندن ندارن بتونن ازش استفاده کنن؟ و این شد که الان دارم این قسمت رو مینویسم :)و اینکه بهتره برای خوندن این سری از مقاله، تجربه قبلی برنامه نویسی داشته باشید(که به احتمال زیاد دارید). چون من نمیام مثلا بگم فلان اکستنشن رو نصب کنید واسه وی اس کد و...ریکت چی هست؟به نقل از خود سایت react.org، ریکت لایبرری ای برای توسعه یو آی وبسایت ها هست. بعضی جا ها به ریکت میگن فریموورک(که اشتباهه. خود تیمشون هم میگن لایبرری هست) به دلیل قدرت بالایی که داره.فواید ریکتشما با ریکت میتونید فرانت اند وبسایت ها رو خیلی راحت تر توسعه بدید. هر قسمت از یو آی وبسایتتون رو میتونید یه کامپوننت(در آینده ای نزدیک توضیح میدم کامپوننت چی هست) در نظر بگیرید و یو آیتون رو به قسمت ها کوچیکی به اسم کامپوننت بشکونید. و بعد همه اونا رو در کنار هم بزارید و یو آی وبسایتتون رو بسازید. این کار باعث میشه دیباگینگ برنامه شما خیلی راحت تر بشه. از طرفی خود ریکت هم واقعا دقیق ارور ها رو اعلام میکنه بهتون. سرعت ریکت، به شدت بالاست. سایت هایی مثل خود ویرگول، نتفلیکس و دراپ باکس و... یکی از دلایل لود شدن سریعشون استفاده از ریکت هست. شما با ریکت میتونید وبسایت های SPA(single page application) بسازید. یعنی اپلیکیشنی که جابه جایی بین صفحاتش بسیار سریع هست به طوری که هرکسی فکر میکنه داره از یه اپ موبایل یا دسکتاپ استفاده میکنه! و جالب تر اینکه url هم تغییر میکنه! چی ازین بهتر؟پیشنیاز یادگیری ریکتریکت تنها پیشنیازش آشنا بودن با جاوا اسکریپت هست. همین! ولی نه آشنا بودن سطحی. باید خیلی خوب باهاش آشنا باشید که بتونید درکش کنید. پس اگر جاوا اسکریپتتون خوب نیست، خواهشا وقتتون رو روی یادگیری ریکت هدر ندید. چون واقعا ازش زده میشید و یه جاهاییش رو اصلا متوجه نمیشید و این ممکنه باعث بشه از یادگیری نه تنها ریکت، بلکه فریموورکا و لایبرریای دیگه جی اس زده بشید.بهترین آی دی ای یا تکست ادیتور از نظر من برای کار با ریکتاز نظر من VSCode بهترین انتخاب برای کد نویسی ریکت هست. و پیشنهاد من استفاده از این تکست ادیتور هست. چون ارور های سطحی رو خیلی خوب پیدا میکنه و مینویسه که باید چه کنیم، وقتی یه کامپوننت رو میخوایم ازش استفاده کنیم نیازی نیست خودمون دستی ایمپورتش کنیم چون خود وی اس کد اتوماتیک اون رو ایمپورت میکنه و و و...نصب و استفاده از ریکتبرای نصب ریکت شما هم میتونید از سی دی ان های اون استفاده کنید و هم میتونید اون رو از npm نصب کنید.  راه اول رو اینجا نمیگم چون خیلی کم هستن ازش استفاده کنن و به پای راه دوم نمیرسه. بریم سراغ راه دوم.قدم اول: برای اینکه لایبرری ریکت رو از npm نصب کنید، باید اول node js رو نصب کنید. اگر نصب ندارید node js رو، میتونید با یه سرچ ساده از سایت node js، اون رو نصب کنید. وقتی این رانتایم رو نصب کردید، npm هم همراهش نصب میشه. البته با یارن هم میتونید ولی من با نود جی اس بهتون میگم.قدم دوم: برای نصب ریکت فقط کافیه ترمینالتون رو به آدرس فولدر مورد نظر باز کنید، و این دستور رو وارد کنید:npx create-react-app &lt;your-folder-name&gt;به جای &lt;your-folder-name&gt; اسم اون فولدری که میخواین ریکت توش نصب بشه یا میخواید ساخته بشه و بعد توش نصب بشه رو بنویسید. دقت کنید که شما با اجرای این دستور، در واقع دارید ریکت رو دانلود میکنید. با هر بار اجرای این دستور، ریکت از نو دانلود و نصب میشه. و بیشتر پیشنهاد میشه با این دستور ریکت رو نصب کنید که جدید ترین نسخه ریکت واستون نصب بشه.شما با وارد کردن دستور npm start توی ترمینالی که آدرسش دایرکتوری پروژه ریکتتون هست، میتونید لوکال هاستتونو بسازید و سپس به صورت زنده تغییراتی که میدید رو از توی مرورگر ببینید.برنامه hello world توی ریکتاگر شما دستور npm start رو اجرا کرده باشید توی ترمینالتون، حتما بعد از ساخته شدن لوکال هاست و باز شدن صفحه وب پروژه تون، طرح آماده ای رو دیدید. خب ما اون رو نمیخوایم. برای حذف اون ها بیاید و فایل هایی که توی عکس مشخص کردم رو پاک کنید.بعدش توی index.html فولدر public، کد هایی که دورش خط کشیدم رو پاک کنید. اگر دوست داشتید کامنت های پیشفرض فایل اچ تی ام ال رو هم پاک کنید.برید توی فولدر src و سپس index.js رو باز کنید و سپس همه کد های موجود رو پاک کنید.خب الان دیگه از شر کد های پیشفرض خلاص شدیم.حالا بریم سراغ ساخت ساده ترین برنامه ای که میشه با ریکت ساخت:توی index.js، اول کلاس ReactDOM از ماژول react-dom رو ایمپورت کنید. به این شکل:import ReactDOM from &amp;quotreact-dom&amp;quotبعدش از متد render کلاس ReactDOM استفاده باید بکنیم برای نمایش یه المنت توی تگ دیوی به آی دی root. به این شکل:ReactDOM.render(&lt;h1&gt;hello world!&lt;/h1&gt;, document.querySelector(&amp;quot#root&amp;quot));این متد دو تا آرگومان اصلی میگیره: آرگومان اول کامپوننت یا تگی هست که میخواید نمایش داده بشه و آرگومان دوم آدرس جایی که میخواید اون کامپوننت یا تگی که توی آرگومان اول گفتید رندر بشه هست که باید با استفاده از document.getElementById یا document.querySelector اون آدرس مشخص کنید. آرگومان سومی هم در کار هست ولی ما نیازش نداریم در اینجا.حالا اگر برید و مرورگرتون رو چک کنید، میبینید تگ h1 با مقدار hello world! به اچ تی ام التون اضافه شده! این احتمالا اولین و ساده ترین برنامه ریکتی شما هست :))بریم سراغ جزئیات بیشتر...همه چیز درباره JSXجی اس ایکس چیست؟اگه دقت کرده باشید، ما توی برنامه هلو وورلد، تگ h1مون رو با تگ اچ تی ام ال نوشتیم. اونم توی فایل جاوا اسکریپتی!!! باید بگم اون سینتکس، بهش میگن جی اس ایکس. جی اس ایکس خیلی شبیه به اچ تی ام ال و ایکس ام ال هست. ریکت اون سینتکس رو برای راحتی کار برنامه نویس ها فراهم کرده. نوشتن جی اس ایکس تا حد زیادی شبیه به نوشتن تگ های اچ تی ام ال هست. ولی خب یه سری تفاوت ها هم داره که جلو تر متوجه میشید.چرا باید از جی اس ایکس استفاده کنیم؟جی اس ایکس سینتکسی نیست که ریکت ما رو برای استفاده ازش اجبار کنه. ولی ریکت به ما پیشنهاد میده که از سینتکس جی اس ایکس استفاده کنیم. چرا؟ چون به شدت خوانایی کد ما رو بیشتر میکنه و ما دیگه نیازی نیست از روش دوم که پیچیدگیش خیلی بیشتره مخصوصا در مواقعی که المنتای تودرتو داریم استفاده کنیم.دیگه سینتکسی که تا حد خیلی زیادی شبیه به اچ تی ام ال هست خوانایی نمیخواد که :))و اینکه این سینتکس پیچیدگی کد ما رو کمتر میکنه. راحت ایونت هامونو اینلاین به المنتامون میدیم بدون اینکه بخوایم با متدی سر و کله بزنیم.(بهش میرسیم)شما میتونید جی اس ایکس رو توی متغیر، آرایه، آبجکت یا... ذخیره کنید و ازون جاهای مختلف استفاد کنید. شما میتونید به صورت شرطی از جی اس ایکس استفاده کنید! مثلا توی یه فانکشن میتونید با ایف و الس بگید اگر متغیر کاربر null بود، تگ جی اس ایکسی P رو برگردون، اگه متغیر کاربر یه اسمی بود، تگ h6 رو برگردون.فکر کنم قانع شدید چرا باید از جی اس ایکس استفاده کنید. واسه راحتی خودتون هم که شده از جی اس ایکس استفاده کنید.چجوری میتونیم به تگ های جی اس ایکسیمون اتریبیوت بدیم؟گفتم سینتکس جی اس ایکس تا حد خیلی زیادی شبیه به اچ تی ام ال و ایکس ام ال هست. توی اچ تی ام ال چطوری به تگ هاتون اتریبیوت میدادید؟ به صورت اینلاین توی بدنه تگ باز. اینجا هم دقیقا همینجوریه. ولی بعضی از اتریبیوت ها اسماشون تغییر کرده. مثلا توی اچ تی ام ال میخواستیم کلاس بدیم به یه تگ، توی بدنه تگ باز مینوشتیم &quot;class=&quot;test ولی توی جی اس ایکس باید بنویسیم &quot;className=&quot;test. به این شکل:&lt;div className=&amp;quottest&amp;quot&gt;&lt;/div&gt;یا مثلا توی جی اس ایکس اگه بخواید اینلاین به تگ هاتون استایل بدید، باید به این شکل عمل کنیم:&lt;div style={{marginTop: &amp;quot20px&amp;quot, backgroundColor: &amp;quot#000&amp;quot}}&gt;&lt;/div&gt;باید اول اتریبیوت style رو بنویسید، بعدش یه آبجکت رو بین دو تا آکولاد تعریف کنید و توی اون آبجکت اسسم استایلتونو رو به صورت کمل کیس وارد کنید و مقدارش هم استرینگ بدید. مثلا اگه میخواستید margin-bottom بدید، باید marginBottom بنویسید توی آبجکت بین آکولاد ها و مقدارتون رو به شکل استرینگ بهش پاس بدید. حالا چرا باید آبجکتون رو بین آکولاد تعریف کنیم؟ بهتون میگم.به چه دلیل باید از {} برای پاس دادن بعضی از مقادیر استفاده کنیم؟کلا وقتی شما میخواید یه مقدار مثل آبجکت، ایندکسی از آرایه، عدد و یا مقدار ریترن شده از یه فانکشن و یا... رو به عنوان اتریبیوت و یا فرزند پاس بدید به یه تگ، باید اون مقدار رو بین دو تا آکولاد بنویسید. مثلا شما میخواید از مقادیر یه متغیر، فانکشن و آبجکت به عنوان فرزند استفاده کنید. به این شکل باید عمل کنیم:const C1 = &amp;quotreact&amp;quotconst C2 = [&amp;quotvue&amp;quot, &amp;quotpixi js&amp;quot, &amp;quotjs&amp;quot];const C3 = { name: &amp;quotangular js&amp;quot };ReactDOM.render(&lt;h1&gt;hello world! {C1} and {C2[0]} and {C3.name}&lt;/h1&gt;,document.querySelector(&amp;quot#root&amp;quot));و ما الان از این مقادیر داریم استفاده میکنیم به عنوان فرزند جی اس ایکس.برای اتریبیوت ها هم دقیقا باید همین کار رو انجام بدید. برای مثال شما یکی از استایل هاتون رو توی یه آبجکت ذخیره کردید. یکی از کلاس هاتون رو توی یه متغیر ذخیره کردید. برای استفاده ازشون باید اینکارو کنید:const myClassName = &amp;quothello&amp;quotconst myStyle = { marginBottom: &amp;quot50px&amp;quot };ReactDOM.render(&lt;h1 className={myClassName} style={myStyle}&gt;hello world!&lt;/h1&gt;,document.querySelector(&amp;quot#root&amp;quot));به همین راحتی!چجوری به تگ های جی اس ایکسی تگ فرزند اضافه کنیم؟دقیقا مثل اچ تی ام ال که مطمئنم میدونید توی اچ تی ام ال چجوری تگ های تو در تو میسازیم و نیازی به توضیح اضافه نیست.راه دوم ساخت تگ های اچ تی ام ال توی ریکت چی هست؟استفاده از React.createElement. این روش بعید میدونم کسی ازش استفاده کنه ولی دونستن اینکه جی اس ایکس چجوری کار میکنه و راه دیگه ساخت تگ های اچ تی ام ال و... خالی از لطف نیست. ببینید شما چه بخواید با جی اس ایکس تگ های اچ تی ام ال رو تعریف کنید چه با استفاده از این متد، یه آبجکت دریافت خواهید کرد که ریکت با استفاده از این آبجکت ها تگ ها رو به اچ تی ام التون اضافه میکنه. پس خروجی هیچ فرقی با هم نداره.برای ساخت تگ با React.createElement شما اول باید کلاس React رو از ماژول react ایمپورت کنید و سپس از createElement استفاده کنید.متد createElement سه تا آرگومان میگیره.آرگومان اول، اسم تگی هست که شما میخواید ساخته بشه، آرگومام دوم آبجکتی از پراپرتی های اون تگ هست مثل className و style و... و آرگومان سوم تگ های فرزند یا تکست کانتنت تگ هست. مثلا برای ساخت یه تگ h1 و نشون دادن اون باید به این شکل عمل کنید:import React from &amp;quotreact&amp;quotconst myH1 = React.createElement(&amp;quoth1&amp;quot, null, &amp;quotcreated by React.createElement&amp;quot);ReactDOM.render(myH1, document.querySelector(&amp;quot#root&amp;quot));ما اینجا با استفاده از createElement تگ h1 با مقدار created by React.createElement ساختیم و اونو توی متغیر ذخیره و سپس رندرش کردیم. به همین سادگی. حالا مثلا اگه بخواید بهش کلاس و اینلاین استایل بدید، باید اینکار رو کنید:import React from &amp;quotreact&amp;quotconst myH1 = React.createElement(&amp;quoth1&amp;quot,{ style: { color: &amp;quotblue&amp;quot, backgroundColor: &amp;quotred&amp;quot }, className: &amp;quoth1&amp;quot },&amp;quotcreated by React.createElement&amp;quot);ReactDOM.render(myH1, document.querySelector(&amp;quot#root&amp;quot));تازه اینجا داریم یه دونه تگ میسازیم... فرض کنید یه تگ داریم با ده تا تگ فرزند. خیلی سخت و پیچیده میشه ساختنش با React.createElement. ولی با jsx مثل اچ تی ام ال تگ های تودر تو رو مینویسیم.حالا فرق jsx با React.createElement چی هست؟ هیچی! فقط سینتکس و یه سری چیزای جزعی! برای مشاهده دو تا تگ با ساختار مشابه و یکی رو با جی اس ایکس و یکی رو با createElement بسازید و اون رو لاگ بگیرید.const myH1_1 = React.createElement(&amp;quoth1&amp;quot,{ style: { color: &amp;quotblue&amp;quot, backgroundColor: &amp;quotred&amp;quot }, className: &amp;quoth1&amp;quot },&amp;quotcreated by React.createElement&amp;quot);const myH1_2 = (&lt;h1 style={{ color: &amp;quotblue&amp;quot, backgroundColor: &amp;quotred&amp;quot }} className=&amp;quoth1&amp;quot&gt;created with JSX&lt;/h1&gt;);console.log(myH1_1);console.log(myH1_2);خروجی این دو تا حد خیلی زیادی شبیه به هم هستن به غیر از یه سری جاهای کوچیک که مهم نیستن. پس به این نتیجه میرسیم که ما با نوشتن تگ با سینتکس جی اس ایکس، انگار داریم تگامونو با React.createElement میسازیم. پس چرا ما باید بیایم از راه ساخت استفاده کنیم؟ واقعا نمیدونم. توی ادامه آموزش و قسمت های دیگه من از جی اس ایکس استفاده خواهم کرد.جی اس ایکس از حملاتی مثل XSS جلوگیری میکنه!حملات xss یا cross site scripting چی هست؟ خیلی ساده میگم. بعضی موقه ها هکر میاد و کاری میکنه توی سایت که وقتی یک کاربر، حالا هر کاربری، اومد و برای مثال روی یه دکمه کلیک کرد، یک سری اسکریپت های مخرب روی سیستمش اجرا بشه. این حمله روش های مختلفی هم داره. مثلا اینطوری که شما یه اینپوت تکست دارید، و کاربر باید اسمشو وارد کنه. اینجا به جای اینکه اسمشو وارد کنه، میاد و یه اسکریپت مخرب وارد میکنه. خیلی ساده گفتم.حالا جی اس ایکس، اینجوری هست که میاد هر چیزی که توی بدنه اش هست رو اول به استرینگ تبدیل میکنه، بعدش میزاره توی دام. برای مثال اگه هکر بیاد و توی اون اینپوت یه تگ اسکریپت که اسکریپتای مخرب رو لود میکنه بزاره و وبسایت ریکتی شما هم اون مقدار به حساب اسم کاربر رو لود بکنه، اون تگ اسکریپت اول تبدیل به رشته میشه و بعدش به دام افزوده میشه! یعنی اینجوری نیست که بیاد و خود اون تگ اسکریپت رو اد کنه به دام. میتونید این رو تست هم بکنید. یه متغیر تعریف بکنید و توش به صورت استرینگ یه تگ اسکریپت بنویسید. بعدش از مقدار اون متغیر توی جی اس ایکستون استفاده کنید. مقدار به صورت استرینگ نمایش داده میشه! هر چند این پیشگیری ای که جی اس ایکس میکنه اینجوری نیست که همه خطرات رو رفع کنه. هکر هنوز هم میتونه ازینکار ها انجام بده که همش بستگی به مدیریت خودتون داره. برای مثال شما اگه اسم کاربر رو از طریق اتریبیوت dangerouslySetInnerHTML که همون innerHtml جاوا اسکریپت هست و ریکت از عمد تغییرش داده به این اسم، نمایش بدید، اگر یه وقت کاربر تگ اسکریپت به جای اسمش وارد کرد، اون تگ به دام افزوده میشه! برای مثال:ReactDOM.render(&lt;h1style={{ color: &amp;quotblue&amp;quot, backgroundColor: &amp;quotred&amp;quot }}dangerouslySetInnerHTML={{ __html: &amp;quot&lt;h3&gt;dont do this!&lt;/h3&gt;&amp;quot }}className=&amp;quoth1&amp;quot&gt;&lt;/h1&gt;,document.querySelector(&amp;quot#root&amp;quot));
در اینجا من به راحتی تگ h3 رو به بدنع تگ h1 اضافه کردم! پس ریکت الکی و از رو شوخی اسم این پراپرتی رو نزاشته dangerouslySetInnerHTML. چون واقعا خطرناک هست.خب این هم از این مقاله. امیدوارم خوشتون اومده باشه. منتظر قسمت دوم باشید :)اگه دوست داشتید لایک کنید مقاله مو. اگه دوست داشتید دنبال کنید من رو. اگه دوست داشتید یه کامنت مثبت و یا انتقاد منطقی بزارید واسم. خلاصه هرکاری دوست داشتید توی زندگیتون انجام بدید؛ هرکاری که به کسی آسیب نزنه و یا غمگینش نکنه :)</description>
                <category>null</category>
                <author>null</author>
                <pubDate>Wed, 02 Feb 2022 11:16:01 +0330</pubDate>
            </item>
                    <item>
                <title>همگام و ناهمگامی و راه حل های آن در جاوا اسکریپت</title>
                <link>https://virgool.io/@undefined/%D9%87%D9%85%DA%AF%D8%A7%D9%85-%D9%88-%D9%86%D8%A7%D9%87%D9%85%DA%AF%D8%A7%D9%85%DB%8C-%D9%88-%D8%B1%D8%A7%D9%87-%D8%AD%D9%84-%D9%87%D8%A7%DB%8C-%D8%A2%D9%86-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-jcs6qxtriqnt</link>
                <description>سلام دوستان. امیدوارم حالتون خوب باشه.همیشه یکی از چیزایی که واقعا واسم نامفهوم و عجیب غریب بود و میفهمیدمش ولی درکش نمیکردم توی جاوا اسکریپت همین synchronous و asynchronous بود :)با گشتن توی سطح اینترنت خوندن مقاله های مختلف تونستم چیزایی رو بفهمم که این دو تا مفهوم رو بتونم توی جاوا اسکریپت درک کنم و میخوام توی این مقاله واستون از چیزایی که فهمیدم در این مورد واستون توضیحاتی بدم که شما هم این دو مفهوم رو خیلی بهتر درک کنید. این مقاله شاید یکم طولانی باشه ولی به احتمال زیاد از خوندن این مقاله پشیمون نمیشید و مفهوم همگامی و ناهمگامی توی جاوا اسکریپت واستون جا میوفته. خب حرف بسه بریم سراغ توضیحات.بزارید الان خیلی ساده واستون معنی همگامی و ناهمگامی رو واستون توضیح بدم.با برنامه نویسی همگام یا synchronous شروع میکنم. این نوع از برنامه نویسی اینجوری هست که توی برنامه شما خط کد ها در هر شرایطی چه 10 دقیقه طول بکشه عملیاتش چه 1 ثانیه، دقیق پشت سر هم اجرا میشن. از خط یک به خط دو. از خط دو به خط سه و ادامه تا اینکه برنامه به جایی برسه که هیچ چیزی برای اجرا نداشته باشه. این سبک از برنامه نویسی یه سری معایبی داره که از جمله این معایب کندی برنامه هست، اتلاف بیهوده وقت، بلاک شدن برنامه و... هست. که البته جاوا اسکریپت هم جزو این دسته از زبون ها هست و اصولا single-thread هست(تک نخ. توضیح میدم در این مورد) برای مثال اگه شما بیاید و یه حلقه تعریف کنید که 10 میلیارد بار یه جمله رو لاگ بگیره، برنامه که چه عرض کنم، خود مرورگر هم به شدت هنگ میکنه و خط های بعد از اون حلقه اجرا نمیشن. که البته چیزی به نام web workers ها اومدن که سعی میکنم توی یه مقاله واستون توضیحش بدم. خب این از برنامه نویسی همگام یا synchronous یا سنکرون یا هرچیزی که شما دوست دارید صداش بزنید.حالا برنامه نویسی asynchronous یا ناهمگام چی هست؟ بزارید مثال قبل رو جوری بگم که انگار به صورت ناهمگام اجرا میشه. گفتیم اون حلقه که ده میلیارد بار یه چیزیو لاگ میگیره اگه به صورت سنکرون باشه، باعث میشه هم خود برنامه و هم خود مرورگر هنگ کنن و برنامه تون فلج بشه. حالا اگه اون برنامه رو به صورت اسنکرون بنویسیم، و اون حلقه رو بدیم به یه thread(نخ) دیگه، اون حلقه دیگه توی روند نخ اصلی برنامه مون دخالت نمیکنه و این باعث میشه برنامه مون به کار خودش توی نخ اصلی ادامه بده درحالی که توی یه نخ دیگه اون لوپ هی داره یه چیزیو لاگ میگیره. خب این خیلی خیلی چیز کاربردی ای هست و واقعا کمک میکنه توی سرعت بخشیدن به برنامه و جلوگیری از هنگ کردن بیخود. خب من توی مطالب قبل چند بار اسم thread(نخ) اوردم. ترد چی هست؟ ما یه ترد اصلی تو اجرای برنامه هامون داریم. بهش میگن main thread. برای اینکه یک سری دستورات رو جدا ازین ترد اجرا کنیم، باید ترد های دیکه ای بسازیم. پس ترد دقیقا چی هست؟ ترد به دستور العمل هایی میگن که به صورت مستقل توسط سی پی یو اجرا میشن. یعنی کد ها توی یه مسیر جدا از main thread و ترد های دیگه اجرا میشن و در نتیجه در روند اجراییشون اختلالی به وجود نمیاد. ترد ها به همدیگه دسترسی دارن.  ترد مفهوم گسترده ای داره و من خیلی خیلی ساده گفتم بهتون. پس برای اطلاعات بیشتر از گوگل کمک بگیرید.تا اینجا امیدوارم با این مفاهیم کنار اومده باشید و تونسته باشید درک کنید این دو تا مفهوم مهم رو. بریم برای ادامه.مشکلات من ازونجایی شروع شد که شنیدم جاوا اسکریپت یه زبان اسنکرون هست و البته رو هوا هم نمیگفتن جاوا اسکریپت اسنکرون هست و مثال هایی از اون هم دیدم. خلاصه قاطی کرده بودم که چرا میگن جاوا اسکریپت اسنکرون هست درحالی که یک نخ بیشتر نداره. واقعا حسابی قاطی کرده بودم و درک نمیکردم چرا اینجوری هست تا اینکه بعد از سرچ های زیاد و مختلف و خوندن چند تا مقاله بالاخره فهمیدم چی به چی هست. بگذریم... بریم سراغ ادامه بحثمون.بزارید چند تا مثال از اینکه میگن جاوا اسکریپت اسنکرون هست واستون بزنیم.setTimeout&#40;(&#41; =&gt; {console.log(&amp;quot1&amp;quot)}, 3000)console.log(&amp;quot2&amp;quot);دوستان فکر میکنید نتیجه این کد چه خواهد بود؟ اگر فکر میکنید نتیجه کد 1 و 2 خواهد بود، متاسفانه در اشتباه هستید. نتیجه این کد 2 و 1 خواهد بود. شاید بگید خب تو که گفتی جاوا اسکریپت سنکرون هست پس چرا این کدا به ترتیب اجرا نمیشن؟ بله هست و من هنوز پای حرفم هستم. الان دلیلشو واستون میگم.Call stackخب خب. این قسمت از مقاله قسمت بسیار جالب و جذابیه و خودم خیلی با فهمیدنش حال کردم و باعث شد نافهوم بودن سنکرون توی جی اس از بین بره واسم =)میدونید که جاوا اسکریپت یه زبان مفسری هست. میدونید که این زبان یک تردی هست. و توی مثال قبل هم که مثال خیلی کوچیکی هم بود دیدید که جاوا اسکریپت اون رو شبیه به یه زبان اسنکرون و چند تردی اجرا کرد. اما واقعیت چیه؟ بالاخره این زبان تک نخی هست یا چند نخی؟ سنکرون هست یا اسنکرون؟توی جاوا اسکریپت یه چیزی هست به اسم call stack(پشته فراخوانی). پشته چی هست؟ببینید ما توی برنامه مون از چیزای مختلفی استفاده میکنیم که فانکشن ها یکی از پر استفاده ترین هاشون هست. ما در اکثر مواقع فانکشن ها رو یه جا تعریف میکنیم و جایی که نیاز داریم ازشون استفاده میکنیم. وقتی شما فانکشن رو یه جایی صدا میزنید، جاوا اسکریپت میاد و این فانکشن رو میندازه جایی به اسم پشته فراخوانی. سپس اون رو اجرا میکنه و وقتی کار اون فانکشن تموم شد، میاد و اون رو از کال استک حذف میکنه. خب شاید زیاد نفهمیدید چی به چی شد. پایین واستون یه قطعه کد میزارم و بعد کال استک کد رو با تصویر بهتون نشون میدم.function sayHello() {console.log(&amp;quothello&amp;quot);
}function sayHowAreYou(params) {console.log(&amp;quothow are you?&amp;quot);}function sayBye() {console.log(&amp;quotbye!&amp;quot);}sayHello();sayHowAreYou();sayBye();مراحل اجرا شدن به این شکل هست:1- مفسر شروع میکنه به خوندن قطعه کد ها.2- کد ها رو میخونه و میخونه و وقتی رسید به فراخوانی فانکشن sayHello، فانکشن رو میندازه توی کال استک.3- سپس مفسر میره برای خوندن قطعه کد های بدنه sayHello. در بدنه، به فراخوانی console.log برخورد میکنه. اینجا دستور لاگ رو هم میندازه توی کال استک.4- مفسر اینجا میاد و دستور لاگ رو انجام میده و سپس اون رو حذف میکنه از کال استک. و میره ادامه خوندن بدنه فانکشن sayHello. وقتی میبینه هیچ دستور دیگه ای برای اجرا نیست، فانکشن sayHello رو هم از کال استک حذف میکنه.پ.ن 1: این اتفاق برای فراخونی فانکشن های بعد از sayHello هم میوفته...پ.ن 2: یادتون باشه مفسر جاوا اسکریپت فانکشنای موجود توی استک رو از بالا به پایین اجرا میکنه!5- بعد اجرا شدن کل دستورات برنامه، کار مفسر تموم میشه و برنامه به پایان میرسه.و اینجوری برنامه ما اجرا میشه.خب بریم یکم مثالمونو پیچیده تر کنیم.function sayHello() {console.log(&amp;quothello&amp;quot);sayHowAreYou();}function sayHowAreYou(params) {console.log(&amp;quothow are you?&amp;quot);sayBye();}function sayBye() {console.log(&amp;quotbye!&amp;quot);}sayHello();خب توی این مثال اجزای برنامه دقیقا شبیه اجزای برنامه مثال قبلی هست. ولی این بار جور دیگه برنامه رو اجرا کردیم. توی گیف پایین میتونید وضعیت لحظه ای کال استک رو ببینید و پایین گیف هم متنی توضیح میدم چجوری این برنامه اجرا میشه.مرحله به مرحله واستون توضیح میدم که توی کال استک چه اتفاقی می افته:1- مفسر جاوا اسکریپت میاد و میبینه فانکشن sayHello فراخونی شده. اونو میندازه توی استک که بهش رسیدگی کنه.2- مفسر میبینه که متد console.log هم فراخونی شده توی بدنه sayHello. این متد رو هم میندازه توی استک که اجراش کنه.3- مفسر کار متد console.log که تموم شد، اون رو از استک حذف میکنه چون کاری باهاش نداره. بعد که میره خط بعد، میبینه که  فانکشن sayHowAreYou فراخونی شده. به همین دلیل اون رو هم میندازه توی استک که بهش رسیدگی کنه.4- حالا مفسر میره دستورات فانکشن sayHowAreYou رو بخونه چون این فانکشن توی بالاترین قسمت استک قرار داره. وقتی داره خط های این فانکشنو میبینه، با متد console.log مواجه میشه و اون رو میندازه توی استک. بعد از مدت خیلی کمی مفسر اون متد رو هم اجرا میکنه و کارشو تموم میکنه.5- مفسر چون کار اجرای پردازش بالاترین متد استک ینی console.log رو تموم کرد، اون متد رو حذف میکنه. این در حالی هست که فانکشن های sayHello و sayHowAreYou هنوز کارشون تموم نشده و تو استک هستن. مفسر بعد ازینکه میره خط بعدی توی بدنه فانکشن sayHowAreYou میبینه که فانکشن sayBye فراخونی شده. این رو هم میندازه توی استک. الان سه تا فانکشن توی استک وجود داره.6- بعد مفسر میره توی بدنه فانکشن sayBye که دستورات دیگه رو تفسیر کنه. به console.log برخورد میکنه و اون رو میندازه تو استک. بعد که مفسر کارش تموم شد، اون رو از کال استک حذف میکنه.7- بعد مفسر میره ببینه کاری توی sayBye نمونده، که متوجه میشه کار دیگه ای نمونده. به همین دلیل sayBye رو حذف میکنه از استک. حالا چون sayHowAreYou در بالاترین قسمت استک هست، اون رو هم چک میکنه و میبینه کار دیگه ای نمونده. به همین دلیل اون رو هم پاک میکنه از استک. الان توی بالاترین قسمت استک sayHello مونده. مفسر اون رو هم چک میکنه و میبینه اونجا هم کاری نیست. به همین دلیل sayHello رو هم از استک حذف میکنه و بدین ترتیب استک خالی میشه و برنامه هم به پایان میرسه.همیشه موقع کد زدن حواستون به استک هم باشه که بیهوده و زیادی پرش نکنید. اگر استک پر بشه با ارور stack overflow مواجه میشید. خب امیدوارم قسمت کال استک رو خوب متوجه شده باشید. بریم سراغ ادامه. در ادامه متوجه سنکرون بودن جاوا اسکریپت میشید.Callback Queue یا Task Queueتوی جاوا اسکریپت، بعضی از متدایی که استفاده میکنیم، مال api خود browser(مرورگر) هستن. بهش هم web apis میگن، هم browser apis. متد هایی مثل setTimeOut یا مثل XMLHttpRequest  و ککللییی متد دیگه مربوط به web apis هست.اینجا میتونید لیست کاملی از متد های web apis رو ببینید که ماشالا تعدادشون هم زیاده.توی جاوا اسکریپت یه چیزی هست به اسم callBack(بازگشت فراخوانی. خواهشا اینطوری صداش نزنید و انگلیسیشو بگید). خب کالبک چی هست؟ کالبک فانکشن ها به فانکشن هایی میگن که به عنوان آرگومان به یه فانکشن دیگه داده میشه و بعد از انجام شدن عملیات ناهمگام(بیشتر واسه عملیات ناهمگام استفاده میشه) اون فانکشن، کال بک فانکشن اجرا میشه و این باعث میشه که عملیات ناهمگام مدیریت بشن. اوایل مقاله یه مثال واستون زدم ازینجور عملیات. یادتون هست؟ الان میخوام با کالبک فانکشن اون مشکل که عدد 2 زودتر از 1 نمایش داده میشد رو حل کنم.setTimeout&#40;(&#41; =&gt; {console.log(&amp;quot1&amp;quot)}, 3000)console.log(&amp;quot2&amp;quot);
//output:
//2
//1


function callBack() {
console.log(&amp;quot1&amp;quot);
 console.log(&amp;quot2&amp;quot)
}
setTimeout&#40;callBack, 3000&#41;;
//output:
//1
//2
متد setTimeout دو تا آرگومان میگیره. یکیش یه کالبک فانکشن هست و دومی تایم اجرای اون کالبک فانکشن. چرا ما کالبک فانکشن میدیم به setTimeout؟ چون میخوایم بعد از انجام شدن عملیات setTimeout فانکشن ما اجرا بشه.توی کد بالا، اول کد مثال اول مقاله رو نوشتم. اگه دقت کنید من به setTimeout یه کالبک فانکشن به عنوان آرگومان پاس دادم. توی کد بعدیش ما مشکلمون رو حل کردیم. این دفعه من برای اینکه یه وقت قاطی نکنید یه فانکشن ساختم به نام callBack و اون رو پاس دادیم به setTimeout که بعد از گذشت 3 ثانیه فانکشنمون درست اجرا بشه و به ترتیب عدد 1 و 2 رو لاگ بگیره. ما میتونستیم همون فانکشن رو توی آرگومان setTimeout تعریف کنیم.پس گفتیم کالبک ها فانکشن هایی هستن که میخوایم بعد از اجرای یه عملیات ناهمگام اجرا بشن!میرسیم به قسمت خیلی مهم مقاله که سنکرون بودن جاوا اسکریپت واستون جا میوفته.گفتیم که ما یه چیزی داریم به اسم web apis و یه چیزی داریم به نام call back. توی جاوا اسکریپت یه مخزن دیگه هست که بهش میگن callBack queue(صف کالبک) که بهش task queue(صف کار) هم میگن.توی کالبک کیو، کالبک فانکشن هایی که میخوایم بعد از اجرا شدن متد های browser apis اجرا بشن قرار میگیرن.بزارین با یه مثال دقیق تر واستون توضیح بدم web apis و call back queue رو.setTimeout&#40;(&#41; =&gt; {console.log(&amp;quotcall stack is free. say hello to call back function.&amp;quot)}, 2000)console.log(&amp;quotcall stack is full&amp;quot)مثال کوچیک ولی مفیدی هست چون با این مثال میخوام توضیحات تکمیلی رو بدم.توی پشت صحنه جاوا اسکریپت یه چیزی هست به اسم event loop(چرخه رویداد). ایونت لوپ مدام در حال چک کردن کال استک و کالبک کیو و چیزای دیگه هست. ایونت لوپ میاد و چک میکنه اگه کال استک خالی بود، و اگه کالبک کیو حداقل یه فانکشن داشت، اون کالبک رو میندازه توی کال استک که اجرا بشه.دقت کنید اجرا شدن فانکشن های توی call stack از اولویت بالاتری برخوردار هست و تا وقتی کال استک خالی نباشه، کالبک فانکشن نمیتونه اجرا بشه.خب من واستون متنی هم توضیح میدم مثالی که من واستون زدم. ولی به گیف هم دقت بکنید حتما. 1- مفسر میاد و از خط اول شروع میکنه و بعد با اولین متد که setTimeout هست مواجه میشه. اونو میندازه تو استک و بعد ایونت لوپ که گفتیم مدام داره بررسی میکنه، میفهمه که اون متد مربوط به وب ای پی آی هاست و به همین دلیل ورش میداره و میندازتش توی قسمت وب ای پی آی.2- اونجاست که وب ای پی آی یه تایمر دو ثانیه ای ست میکنه که اون فانکشن ناشناسی(anonymous function) که ما بهش پاس دادیم رو بعد ازینکه تایمر تموم شد ایونت لوپ بندازتش تو کالبک کیو.3- مفسر خط های بعد رو میره میخونه و با console.log مواجه میشه. اون رو میندازه توی کال استک تا اجراش کنه. وقتی اجراش کرد اون رو از استک حذف میکنه.4- الان استک خالی هست و وب ای پی آی تایمرش تموم شده و ایونت لوپ کالبک فانکشن رو انداخته توی کالبک کیو. به همین دلیل وقتی ایونت لوپ میرسه به کالبک کیو، و میفهمه که استک خالی هست، فانکشن ناشناس ما رو میندازه توی استک که اجرا بشه. وقتی مفسر میره توی بدنه فانکشن، دوباره با console.log مواجه میشه و اونو میندازه تو استک. و وقتی اجراش کرد اون رو حذف میکنه و چون فانکشن ما به پایان رسیده اون رو هم از استک حذف میکنه و برنامه به پایان میرسه.الان دیگه فکر کنم متوجه شدید چرا جاوا اسکریپت سنکرون هست ولی بعضی از دستور هاش به صورت اسنکرون اجرا میشه و اسنکرون بودن رو شبیه سازی میکنن :)setTimeout&#40;(&#41; =&gt; {console.log(&amp;quot1&amp;quot)}, 0)console.log(&amp;quot2&amp;quot)حالا شما بگید خروجی این کد چی هست.promiseتوی جاوا اسکریپت یه چیزی هست به اسم promise. چون یه چیز دیگه مثل کالبک کیو توی جاوا اسکریپت هست و مربوط به پرامیس ها هست، یکم از پرامیس ها هم حرف میزنم ولی کامل نیست و سعی میکنم یه مقاله کامل راجع بهش بنویسم و اینجا هم حتما لینکشو خواهم گزاشت.خب پرامیس رو چجوری میشه تعریف کرد؟ اینجوری:let myPromise = new Promise((resolve, reject) =&gt; {resolve(&amp;quothey! the promise was successful&amp;quot)});برای ساخت میتونیم از کلاس پرامیس استفاده کنیم که متد سازنده این کلاس، به یه executor function(تابع مجری. من همون اگزکیوتر صداش میزنم) نیاز داره که حداقل باید شامل یک آرگومان باشه. آرگومان اولی برای فرستادن اطلاعات در صورت موفق بودن عملیات هست، آرگومان دوم برای فرستادن اطلاعات یا ارور یا هرچیز دیگه ای در صورت شکست عملیات هست. تو این مقاله من فرض میکنم عملیات همیشه موفق هست.برای اعلام شکست عملیات، باید reject رو فراخوانی کرد و برای اعلام موفقیت برنامه باید resolve رو فراخونی کرد.حالا برای دریافت اطلاعات در صورت موفق بودن اجرا توی پرامیس باید چیکار کرد؟ باید از .then() استفاده کرد. برای دریافت اطلاعات در صورت شکست هم باید از .catch() استفاده کرد. این دو تا متد هم هرکدومشون یه آرگومان باید داشته باشن که اطلاعات موفقیت یا شکست توی اون آرگومان ذخیره میشه. به این شکل:myPromise.then((success_value) =&gt; {console.log(success_value);}); 
//outputکلا وقتی دیدن کالبک فانکشن ها بعضی جاها خیلی پیچیدگی و ناخوانایی به وجود میاره و خیلی دیباگ کردن در بعضی مواقع سخت میکنه، اومدن و پرامیس ها رو اوردن که خیلی تاثیرات مثبتی داشتن توی کد و تقریبا مثل کالبک فانکشن ها عمل میکنن. البته هنوز هم از کالبک فانکشن ها استفاده میشه. مثلا توی حلقه forEach. هنوز هم خیلی استفاده میشه چون همونطور که گفتم در بعضی مواقع پیچیدگی و ناخوانایی اضافه میکنه به کد. برای دیدن نمونه ای ازین پیچیدگی های وحشتناک، عبارت callBack hell رو گوگل کنید.یه چیز دیگه رو که نیاز هست توضیح بدم اینه که مفسر وقتی به پرامیس برخورد میکنه، درجا اگزکیوتر فانکشنشو میندازه توی کال استک و اجراش میکنه. برای مثال اینجا رو ببینید:let myPromise = new Promise((resolve, reject) =&gt; {
console.log(&amp;quothaha you didnt use .then() but im running!&amp;quot)resolve(&amp;quothey! the promise was successful&amp;quot)});

console.log(&amp;quotthere is a text before me!&amp;quot)
همونطور که گفتم مفسر وقتی داره خط ها رو میخونه، اگه به پرامیس برخورد کنه، درجا اگزکیوتر فانکشنشو میندازه توی کال استک و وقتی کار اگزکیوتر فانکشن تموم شد اون رو از کال استک حذف میکنه. و بعدش میره سراغ console.log دوم و کارای اون رو انجام میده.توی جاوا اسکریپت یه چیز دیگه مثل کالبک کیو هست به اسم job queue(صف کار). این صف مختص پرامیس ها هست. فانکشنی که شما پاس میدید به .then یا .catch، انداخته میشن توی جاب کیو و دقت کنید «فقط وقتی فانکشن های توی جاب کیو اجرا میشن به ترتیب، که کال استک خالی خالی باشه».بزارید اولویت اجرایی یه برنامه رو به ترتیب بهتون بگم:1- کال استک2- جاب کیو3- کالبک کیوپس اگه دیدید فانکشن های جاب کیو زودتر اجرا شدن تعجب نکنید چون این به دلیل اولویت هست.یه چیز جالب دیگه که باید بگم این هست که توی پرامیس وقتی یه چیزی ریزالو یا ریجکت میشه، درجا اون فانکشن پاس شده شما به .catch یا .then اضافه میشه به جاب کیو. و بعد برنامه ادامه پیدا میکنه تا وقتی کال استک تموم بشه. بعدش که تموم شد تک تک آیتمای جاب کیو به ترتیب انداخته و اجرا میشن توی کال استک. resolve حکم صدا زدن کالبک واسه ما داره.بزارید واستون مثال بزنم.let myPromise1 = new Promise((resolve, reject) =&gt; {console.log(&amp;quothey! im the first promise&amp;quot)resolve(&amp;quota message from promise1!&amp;quot)})let myPromise2 = new Promise((resolve, reject) =&gt; {console.log(&amp;quothey! im the second promise&amp;quot)resolve(&amp;quota message from promise2!&amp;quot)})function getResolve1() {myPromise1.then(function run1(value) {console.log(value)});getResolve2()}function getResolve2() {myPromise2.then(function run2(value) {console.log(value)});}
getResolve1()
خب. گفتیم مفسر تا به پرامیس برخورد کرد، اگزکیوتر فانکشنشو اجرا میکنه و توی اگزکیوتر فانکشن وقتی برسه به resolve درجا فانکشنی که پاس دادیم به .then مربوطه رو میندازه توی جاب کیو.خب قدم به قدم واستون توضیح میدم طرز اجرا شدن این برنامه رو:1- مفسر به پرامیس اول برخورد میکنه. اگزکیوتر فانکشنشو میندازه توی کال استک و بعد توی بدنه، به دستور لاگ برخورد میکنه. اون رو هم میندازه توی کال استک و اجرا میکنه و بعد حذف میکنه و بعدش به ریزالو برخورد میکنه. اینجا هست که فانشکن run1 توی جاب کیو انداخته میشه.2- توی خط بعدی که پرامیس دوم رو تعریف کردیم هم همینطوری اجرا میشه و وقتی توی اگزکیوتر فانکشن به ریزالو برخورد میکنه فانکشن run2 انداخته میشه توی جاب کیو و بعد که به پایان اگزکیوتر فانکشن رسید، اگزکیوتر فانکشن رو از کال استک رو حذف میکنه. پس تا اینجا توی جاب کیو، دو تا فانکشن run1 و run2 هست.3- برنامه ادامه پیدا میکنه تا اینکه برسه به getResolve1. بعدش اون فانکشن رو میندازه توی کال استک. گفتیم که دستور .then اجرا شده. پس میره خط بعدی و اینجا به getResolve2 برخورد میکنه. اون رو هم میندازه توی کال استک. توی این فانکشن هم .then اجرا شده. اینجاست که برنامه ما تقریبا تموم شده. پس میاد فانکشن های getResolve1 و getResolve2 رو حذف میکنه.4- ایونت لوپ میبینه که توی جاب کیو دو تا فانکشن هست. پس میاد از سمت راست به چپ(قدیم به جدید)، اون ها رو میندازه توی کال استک. اول فانکشن run1 انداخته میشه توی کال استک. مفسر میره برای اجرا. دستور لاگ رو میبینه. اون رو هم میندازه توی کال استک و اجراش میکنه. بعد دستور لاگ رو حذف میکنه. بعد که ایونت لوپ میبینه run1 تموم شده اون رو هم حذف میکنه. و برای run2 هم همینجوری هست دقیقا. بعد از اجرای run2، برنامه به پایان میرسه.و این هم از این مقاله :)قبل ازینکه مقاله رو رسما به پایان برسونم جا داره دو تا سایت رو برای انجام تست اجرا بهتون معرفی کنم که قدم به قدم بهتون نشون میده چجوری اجرا میشه یه برنامه و میتونید کد مثال های من رو هم کپی کنید و اونجا ببینید چگونگی اجرا شو.سایت اول: https://www.jsv9000.app/سایت دوم: http://latentflip.com/loupeالبته هرکدوم از این سایت ها یه سری چیز ها رو کم دارن ولی برای یادگیری عالی هستن. مثلا سایت اول قسمت web apis رو نداره و console.log رو نمینندازه توی کال استک. سایت دوم web apis رو داره ولی از پرامیس ها پشتیبانی نمیکنه و فانکشن هاتون باید معمولی باشه نه به شکل arrow. و رسیدیم به پایان مقاله. سعی کردم مفهوم همگام بودن و ناهمگام بودن جاوا اسکریپت رو واستون توضیح بدم نه اینکه صرفا بگم همگام میشه این، ناهمگام میشه اون. و همچنین بهتون راه های مقابله با این ناهمگامی رو هم بگم بهتون که با معرفی پرامیس ها و کالبک ها این ها رو هم گفتم.خب امیدوارم از این مقاله خوشتون اومده باشه و مفهوم همگام و ناهمگام بودن جاوا اسکریپت رو واستون جا انداخته باشم. اگه دوست داشتید لایک کنید مقاله مو. اگه دوست داشتید دنبال کنید من رو. اگه دوست داشتید یه کامنت مثبت و یا انتقاد منطقی بزارید واسم. خلاصه هرکاری دوست داشتید توی زندگیتون انجام بدید؛ هرکاری که به کسی آسیب نزنه و یا غمگینش نکنه   :)</description>
                <category>null</category>
                <author>null</author>
                <pubDate>Tue, 11 Jan 2022 00:28:21 +0330</pubDate>
            </item>
                    <item>
                <title>Closures در جاوا اسکریپت</title>
                <link>https://virgool.io/@undefined/closures-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-uusjqectjb2u</link>
                <description>سلام سلام. این اولین مقاله من توی ویرگول هست و امیدوارم خوشتون بیاد.خب...توی این مقاله میخوام راجع به کلوژر ها(closures) توضیحاتی بدم.1- کلوژر چیه؟ کلوژر به اون فانکشن یا فانکشن هایی میگن که توسط یه فانکشن دیگه به شما برگشت داده میشه. مثلا فانکشن name به شما یه فانکشن lastName بر میگردونه و میتونید ازون استفاده کنید. در اینجا lastName کلوژر هست.2- کلوژر ها چه فایده ای برای برنامه نویس دارن؟ یکی از فوایدش امنیت هست که وقتی رفتم سراغ توضیحات بیشتر، میفهمید چرا میگم امنیت. یکی دیگه از فوایدش اینه که میتونید اطلاعاتتون رو پایدار نگه دارید! در حالی که اگه از کلوژر استفاده نکنیم، اون متغیر ما توی فانکشن ایجاد میشه و وقتی فانکشن کارشو انجام داد پاک میشه. خیلی جالبه، نه؟ حالا در ادامه بیشتر توضیح میدم.2- ویژگی کلوژر ها چیه؟ یکی از ویژگی هاش که خیلیا به همین دلیل ازش استفاده میکنن این هست که اولویت اولش متغیر های محلی اون فانکشن و بعد متغیر های گلوبال هست و این عالیه!خب گفتم کلوژر به فانکشنی میگن که توسط یه فانکشن دیگه ریترن میشه. الان توی کد بهتون نشون میدم.ساخت فانکشنی برای برگرداندن یک کلوژرخط 2 تا 10، فانکشنی رو ساختم که به من یک کلوژر بر میگردونه. در واقع اول برای من &quot;here is your closure:&quot; رو لاگ میگیره بعد کلوژر فانکشن منو بر میگردونه. خط 7 تا 9 همون کلوژر فانکشنی هست که ازش میگفتم رو بر میگردونه به من. خط 13 اون فانکشن برگشت داده شده رو ذخیره میکنم که بعدا ازش استفاده کنم. چون فانکشن اجرا میشه موقع ذخیره کلوژر فانکشن، قبلش &quot;here is your closure:&quot; لاگ گرفته میش. البته اینم بگم که شما میتونید اینجوری getClosure()() هم از کلوژر فانکشنتون استفاده کنید ولی چون با هربار اینکارو کردن فانکشن getClosure دوباره اجرا میشه و خوانایی کد رو کمتر میکنه و کاربرد کلوژر رو نداره، من ترجیح میدم اون رو ذخیره کنم و احتمال میدم شما هم اینکار رو ترجیح بدید. من توی خط 17 از کلوژر فانکشنم استفاده میکنم. دقت کنید اینجا دارم از فانکشنی که توی خط 7 تا 9 به من برگشت داده میشه استفاده میکنم نه از خود فانکشن getClosure.  پس &quot;hello! im a closure :)&quot; برای من لاگ گرفته میشه. به همین سادگی من از یک کلوژر فانکشن استفاده کردم :)خب آیا کلوژر فانکشن فقط واسه این کار استفاده میشه؟! معلومه که نه! یادتونه از امنیت اطلاعات و استفاده و تغییر یک مقدار توی یک فانکشن حرف زدم؟ الان بهتون با یه مثال اونارو توضیح میدم.امنیت  و پایداری اطلاعات توی یک فانکشنخب این فانکشن کارش اینه که با استفاده از کلوژر فانکشن، کلمه به متغیر بدنه فانکشن که sentence هست اضافه کنه. ولی این بار یه سری چیزای دیگه هم هست که باید بدونید.میدونید که هربار که یه فانکشن صدا زده میشه، متغیر ها و چیزای دیگه که به وجود میان، با یه برند دیگه ساخته میشن(فکر کنم رسوندم منظورو) و بعد از به پایان رسیدن عملیات، اون متغیر ها و چیزای دیگه از بین میرن و دیگه اصلا وجود نخواهند داشت که بتونیم از تغییرات اعمال شده روشون استفاده کنیم. اینجاست که بحث ثابت بودن اطلاعات پیش میاد. چطور من میتونم هر لحظه به متغیر ساخته شده توی فانکشن دسترسی داشته باشم و اونو تغییر بدم اگه خواستم یا ازش استفاده کنم بدون اینکه نگران از بین رفتنش باشم؟ با کلوژر فانکشن. توی این کد دقیقا همینکار رو انجام میدیم. البته اینو بگم که تغییرات روی فانکشن اصلی ایجاد نمیشن. تغییرات روی کپی ای که از فانکشن گرفتیم اجرا میشن و شما میتونید هزار تا کپی از فانکشن getClosure بگیرید و ذخیره کنید و استفاده کنید ازشون که اینجا ما توی createSentences این کپی رو ذخیره کردیم و از کلوژر فانکشن ریترن شدش که روی کپی فانکشن اثر میزاره استفاده میکنیم. توی خط 17 تا 20، هر بار یه کلمه به sentence توی کپیش که createSentences هست اضافه میشه و درجا مقدار لحظه ای sentence لاگ گرفته میشه. این یعنی پایداری اطلاعات توی فانکشنمون! و این یعنی ما دیگه نیازی نداریم که یه متغیر گلوبال توی بدنه خود فایل جی اس تعریف کنیم! و این یعنی امنیت اطلاعات و کسی نمیتونه مقداری که توی sentence هست رو بگیرتش و فقط میتونه اونو ببینه و تغییرش بده تا زمانی که شما بخواید(ادامه داره هنوز :) ). و اینکار نگرانی شما رو که از دست دادن متغیر های توی بدنه فانکشن و امنیتشون هست رو از بین میبره! حتما این کد ها رو خودتون هم تست کنید.تا اینجا به احتمال زیاد قشنگ فهمیدید و درک کردید که کلوژر فانکشن چی هست، به چه درد میخوره و چجوری ازش استفاده میشه. حالا یه چیز جالب تر. ما میتونیم چندین کلوژر فانکشن از یه فانکشن ریترن کنیم! چجوری؟ با استفاده از آبجکت ها.برگرداندن مجموعه ای از کلوژر فانکشن ها(شاید واقعا این نباشه ولی من اینو بهش میگم :) )میبینید؟ انصافا خیلی موضوع جالب و کاربردی ای هست این موضوع!این دفه، فانکشن ما به جای یه دونه کلوژر فانکشن یه آبجکت 4 تایی از کلوژر فانکشن ها که به ترتیب کارایی هرکدوم عبارتند از: اضافه کردن کلمه به جمله، لاگ گرفتن جمله حال حاضر، حذف کلمه به مقدار مورد نیاز و برگرداندن جمله حال حاضر، برمیگردونه. و برای اینکه بهتون ثابت کنم تمام تغییرات، پایداری و امنیت توی کپی اون فانکشن ذخیره و انجام میشن، یه کپی دیگه از getClosure ریختم توی متغیر sentence2 و اگه شما این کد رو تست کنید، متوجه میشید در آخر مقادیر sentence توی sentence1 و sentence2 باهم دیگه فرق دارند. یه نکته خیلی مهم که نیازه بهتون بگم اینه که اگه یه کپی از فانکشنی که کلوژر فانکشن بر میگردونه گرفتید و ذخیره کردید توی یه متغیر و بعدش دقیقا همون متغیر حاوی کپی رو انتسابش دادید به یه متغیر دیگه، هر تغییری روی sentence هرکدوم اعمال بشه، روی بقیه هم اعمال میشه. چرا؟ چون قشنگ از یه برند هستند. این موضوع برای آرایه ها هم همچین چیزی هست. شما اگه دو تا متغیر بسازید و مقدار [1,2,3,4,5] رو بریزید تو هردوشون و مقایسه شون کنید مقدار false رو خواهید دید. ولی اگه به یکیشون [1,2,3,4,5] انتساب بدید و سپس خود همین متغیر رو توی متغیر دیگه بریزید و باهم مقایسه شون کنید، این دفعه مقدار true رو خواهید دید. چرا؟ چون از یه برند هستند و برند اولویت مقایسه هست. امیدوارم چرایی این موضوع رو به خوبی توضیح داده باشم و متوجه شده باشید.اگه دوست داشتید لایک کنید مقاله مو. اگه دوست داشتید دنبال کنید من رو. اگه دوست داشتید یه کامنت مثبت و یا انتقاد منطقی بزارید واسم. خلاصه هرکاری دوست داشتید توی زندگیتون انجام بدید؛ هرکاری که به کسی آسیب نزنه و یا غمگینش نکنه   :)تا مقاله های بعدی خدا نگهدار</description>
                <category>null</category>
                <author>null</author>
                <pubDate>Sun, 12 Dec 2021 01:00:10 +0330</pubDate>
            </item>
            </channel>
</rss>