تابستون داره تموم میشه ها، فرصت‌ها محدودن کلی آفر جذاب در کمپین تابستون🔥👇
۰ ثانیه
۰ دقیقه
۰ ساعت
۳ Erfan Soori
closure & updates
مجتبی سوری حل شده توسط مجتبی سوری

سلام استاد گرامی خسته نباشید

برای یاد آوری کد من اون رو اینجا میگذارم:

import React, { useState, useEffect } from 'react'
export default function Count() {
   const [count, setCount] = useState(0)
   function increment() {
       setTimeout(() => {
           setCount(prevCount => prevCount + 1)
           console.log(count);
       }, 2000)
   }
   // function increment() {
   //     setTimeout(() =>{
   //        setCount(count+1)
   //         console.log(count);
   //     }, 2000)
   // }
   function decrement() {
       setTimeout(() => {
           setCount(count - 1)
       }, 2000)
   }
   useEffect(() => {
       console.log('effect');
   })
   return (
       <div className='counter'>
           <button onClick={decrement} className='bg-info'>-</button>
           <p className='count'>{count}</p>
           <button onClick={increment} className='bg-success'>+</button>
       </div>
   )
}

 

و حالا سوال:

آیا این خاصیت که در این حالت از کد:

 


function increment() {
       setTimeout(() =>{
          setCount(count+1)
           console.log(count);
       }, 2000)
   }


مقدار count در فراخوانی‌های بعدی increment همچنان همان مقدار قدیمی است مرتبط با بحث closure هاست؟

 

آیا میتوانیم نتیجه بگیریم که در هر بار render که در update  اتفاق می‌افتد متغیر‌های ما مانند count و توابع ما مانند increment و  decrementمجددا در مکانی دیگر از حافظه تعریف و مقدار دهی میشوند ؟

 

فرض می‌کنیم در زمان t=۰s increment فراخوانی شده و بعد در زمان t=۱.۵s مجددا فراخوانی شده باشد. در این صورت از زمان t=۲s به بعد ما دو مقدار برای count داریم؛ مقدار فعلی و مقدار قبلی که قرار است در t=۳.۵s چاپ شود. آیا این به آن معناست که اصلا از اول تابع setTimeout  بعنوان ورودی چنین چیزی گرفته:

(شما در قسمتی از ویدیو برای تفهیم مطلب اینطور نوشتید:)


   setTimeout(() =>{
       setCount(0+1)
        console.log(0);
    }, 2000)
        

    و یا اینکه دو تا مکان مجزا در حافظه  و دوتا count داریم؟

 

 

سلام عرفان عزیز

یک نکته رو همیشه تو ذهنت داشته باش react چیزی خارج از  JS نیست یعنی هر مفهومی که در JS هست در اینجا هم همون!!

این موضوع برمیگرده به Stale Closure که در جلسات  کامل در این مورد صحبت کردم و نمیخوام دیگه این مورد رو اینجا تکرار بکنم.

 

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

 

اون مورد اخری که گفتی درست نیست. زمانی که تابع فراخوانی میشه مقدار دهی میشه

 

 

بهترین پاسخ
مجتبی سوری ۲۸ اردیبهشت ۱۴۰۰، ۱۴:۵۳

سلام وقت بخیر

حالت اول setCount(count + 1) دقیق متوجه نشدم که چی شد و چرا تبدیل شد به تابع prevCount => prevCount+1

چون حالت اول هم باز 0 تایپ میشد حالت دوم هم صفر ولی با این تفاوت که تو حالت دوم با هر بار کلیک کامپوننت دوباره رندر میشه

 

ممنون میشم توضیح بدین

Daniel Mcmahan ۰۵ خرداد ۱۴۰۰، ۰۵:۰۳

بحثی که وجود داره این که در زمانی که تابع setCount رو داریم فراخوانی میکنیم از آخرین مقداری که count داره استفاده بکنیم یا نه؟

اگر بخوایم از اخرین مقدار استفاده بکنیم باید به setCount تابع پاس بدیم. اگر مستقیم از مقدار count استفاده بکنیم در زمان کلیک کردن count هر مقداری داشته باشه از همون استفاده میشه حتی اگر مقدار count در این بازه زمانی ۲ ثانیه هم تغییر بکن

مجتبی سوری ۰۵ خرداد ۱۴۰۰، ۰۵:۴۹