TGViewer
Channel Public Channel
Perfino🌱

Perfino🌱

@perfino_com

💡 Coding tips

🌱 From my real experiences
Instagram:@_perfino

@per_fino
Subscribers
64
Photos
55
Videos
3
Links
9
Recent Posts 19 shown
Post #110 67
Perfino🌱 {ریکت}: همیشه میگن " state رو mutate نکن " خب این یعنی چی؟ 1. اول معنی خود کلمه Mutation یعنی تغییر دادن چیزی در جای خودش، بدون ساختن نسخه جدید 2. چه چیزهایی mutate می‌کنند؟ Mutation روی چیزهایی معنا دارد که قابل تغییر هستند. در جاوااسکریپت این‌ها…
حالا چرا در ری‌اکت می‌گوییم state را mutate نکن؟

برگرد به مفهوم snapshot که در پیام قبلی گفتم. ری‌اکت برای اینکه بفهمد state عوض شده، به هویت مرجع (reference identity) نگاه می‌کند، نه به محتوایش.

بگذار با کد نشان بدهم:

  const [todos, setTodos] = useState([{ id: 1, text: 'خرید' }]);

  function addTodo() {
    // این غلط است
    todos.push({ id: 2, text: 'ورزش' });
    setTodos(todos);
  }

  return (
    <ul>
      {todos.map(t => <li key={t.id}>{t.text}</li>)}
    </ul>
  );
}

چه اتفاقی می‌افتد وقتی addTodo اجرا شود؟

1. todos.push(...) آرایه‌ی فعلی را در جای خودش تغییر می‌دهد.
2. حالا todos هنوز همان مرجع قبلی است. همان آدرس حافظه. فقط محتوایش عوض شده.
3. setTodos(todos) صدا زده می‌شود، اما todos همان reference قبلی است.
4. ری‌اکت می‌گوید: «مرجع عوض نشده. پس این state تغییر نکرده.» و رندر دوباره را انجام نمی‌دهد.
5. UI آپدیت نمی‌شود. آیتم جدید نمایش داده نمی‌شود.

این باگ کلاسیک mutation است. کد به‌نظر درست کار می‌کند اما UI عوض نمی‌شود.


۴. نسخه درست همان کد
  const [todos, setTodos] = useState([{ id: 1, text: 'خرید' }]);

  function addTodo() {
    // این درست است
    setTodos([...todos, { id: 2, text: 'ورزش' }]);
  }

  return (
    <ul>
      {todos.map(t => <li key={t.id}>{t.text}</li>)}
    </ul>
  );
}

اینجا چه کردیم؟

· [...todos, newItem] یک آرایه جدید ساخت. آرایه قبلی دست‌نخورده مانده.
· این آرایه جدید مرجع جدیدی دارد.
· setTodos این مرجع جدید را می‌گیرد.
· ری‌اکت می‌بیند مرجع عوض شده، پس رندر دوباره می‌کند.
· UI آپدیت می‌شود.

این تفاوت بین mutation و immutable update است.
@perfino_com
Post #109 53
{ریکت}:

همیشه میگن " state  رو mutate  نکن "

خب این یعنی چی؟

1. اول معنی خود کلمه Mutation

یعنی تغییر دادن چیزی در جای خودش، بدون ساختن نسخه جدید

2. چه چیزهایی mutate می‌کنند؟

Mutation روی چیزهایی معنا دارد که قابل تغییر هستند. در جاوااسکریپت این‌ها را mutable می‌گوییم:

· آرایه‌ها: push, pop, shift, unshift, splice, sort, reverse همه mutate می‌کنند.

· آبجکت‌ها: obj.key = value, delete obj.key mutate می‌کنند.

· Map و Set: متدهایشان mutate می‌کنند.

در مقابل، این‌ها mutate نمی‌کنند (immutable operation):

· رشته‌ها (string): همیشه immutable هستند.

· اعداد و boolean: immutable هستند.

· متدهای غیرمخرب آرایه: map, filter, slice, concat, flatMap — این‌ها آرایه جدید می‌سازند.

پس mutate کردن یعنی استفاده از متدها یا عملیاتی که شیء اصلی را در جای خودش تغییر می‌دهند.


3.چرا ریکت به این سخت‌گیری نیاز داره؟

قابلیت‌های پیشرفته ری‌اکت:

چیزهایی مثل React.memo، useMemo، useCallback، زمان‌بندی هوشمند رندر (Concurrent)، همه به این وابسته‌اند که stateها immutable باشند. اگر mutate کنی، این ابزارها فریب می‌خورند.

مثالش پایینه 👇🏻


@perfino_com
Post #108 53
#ایده_تمرین_ریکت


@perfino_com
  • 👍 1
  • 🔥 1
  • 🥰 1
  • 🤝 1
Post #107 60
Perfino🌱 مفهوم Snapshot در ری‌اکت این یکی از مهم‌ترین مفاهیمی است که اگر درست بفهمی، نصف باگ‌های عجیب ری‌اکت برایت قابل توضیح می‌شود. بگذار از پایه شروع کنم. ۱. اول ببینیم واقعاً چه اتفاقی می‌افتد فرض کن این کامپوننت را داری: function Counter() { const [count…
اگه داری ریکت میخونی حتما به این مبحث دقت کن و مفهومش دقیق یادبگیر

(درسته متنش طولانیه ولی اصولیه)
Post #106 58
مفهوم Snapshot در ری‌اکت

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



۱. اول ببینیم واقعاً چه اتفاقی می‌افتد

فرض کن این کامپوننت را داری:
function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>شمارنده: {count}</p>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  );
}

وقتی کاربر روی دکمه می‌زند:

1. setCount(count + 1) صدا زده می‌شود.
2. ری‌اکت می‌گوید: «state عوض شد. باید این کامپوننت را دوباره اجرا کنم.»
3. کل تابع Counter از نو اجرا می‌شود. (این خیلی مهم است)
4. این بار count مقدار جدیدی دارد، پس JSX جدیدی برگردانده می‌شود.
5. ری‌اکت این JSX جدید را با JSX قبلی مقایسه می‌کند (diffing) و فقط تفاوت‌ها را روی DOM واقعی اعمال می‌کند.

این «اجرای مجدد تابع» همان چیزی است که به آن re-render می‌گوییم.



۲. حالا snapshot یعنی چه؟

وقتی می‌گویم «هر بار state عوض می‌شود، ری‌اکت یک snapshot جدید می‌سازد»، منظورم این است:

هر بار تابع کامپوننت اجرا می‌شود، تمام مقادیر state و props آن اجرا، مثل یک عکس فوری، قفل می‌شوند. آن اجرا، آن مقادیر را برای همیشه دارد. این عکس فوری هرگز تغییر نمی‌کند.

بگذار با یک مثال concrete نشانت بدهم:
function Counter() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return <button onClick={handleClick}>{count}</button>;
}

بیایم مرحله به مرحله ببینیم چه اتفاقی می‌افتد:

اجرای اول (initial render):

· count = 0
· تابع handleClick ساخته می‌شود. این تابع الان count = 0 را در خودش «قفل» کرده.
· JSX: <button>0</button>
· این یک snapshot است: { count: 0, handleClick(نسبت به count=0) }

کاربر کلیک می‌کند:

· handleClick اجرا می‌شود.
· داخلش count همان 0 است (چون در snapshot اول قفل شده).
· setCount(0 + 1) یعنی setCount(1).
· ری‌اکت می‌گوید state عوض شد. کامپوننت را دوباره اجرا کن.

اجرای دوم (re-render):

· count = 1
· یک handleClick جدید ساخته می‌شود. این تابع جدید count = 1 را قفل کرده.
· JSX: <button>1</button>
· snapshot جدید: { count: 1, handleClick(نسبت به count=1) }

کاربر دوباره کلیک می‌کند:

· handleClick جدید اجرا می‌شود.
· این بار count همان 1 است.
· setCount(1 + 1) یعنی setCount(2).

و به همین ترتیب...

نکته کلیدی اینجاست: هر snapshot، مستقل و جدا از snapshotهای دیگر است. مقادیر داخلش هرگز تغییر نمی‌کنند. وقتی می‌گوییم state عوض شد، در واقع داریم یک snapshot جدید می‌سازیم، نه اینکه داخل snapshot قبلی دست ببریم.


۳. اشتباه رایجی که این مفهوم را روشن می‌کند

این کد را ببین:
function Counter() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
    setCount(count + 1);
    setCount(count + 1);
  }

  return <button onClick={handleClick}>{count}</button>;
}

سوال: اگر کاربر کلیک کند، count چند می‌شود؟

جواب شهودی: «3 تا اضافه شده، پس می‌شود 3.»

جواب واقعی: می‌شود 1.

چرا؟ چون در این snapshot، count = 0 است. هر سه فراخوانی setCount، مقدار 0 + 1 = 1 را می‌فرستند. ری‌اکت سه بار می‌گوید «1 شو» که در نهایت همان 1 می‌شود.

این دقیقاً همان مفهوم snapshot است. count که داخل handleClick می‌بینی، همان مقدار قفل‌شده در snapshot جاری است. همه‌جا در این اجرا، count فقط یک معنا دارد: 0.

اگر بخواهی این 3 تا واقعاً جمع شوند، باید از فرم تابعی استفاده کنی:
setCount(prev => prev + 1);
setCount(prev => prev + 1);
setCount(prev => prev + 1);

چون اینجا به count قفل‌شده دست نمی‌زنی، بلکه به ری‌اکت می‌گویی: «آخرین مقدار state را بگیر و یکی اضافه کن.» ری‌اکت این کارها را به ترتیب انجام می‌دهد و می‌شود 3.




@perfino_com
  • 👏 1
Post #105 57
یک تمرین چک لیست متفاوت با ریکت
#ایده_تمرین


@perfino_com
  • 👏 3
  • 👍 1
  • 🔥 1
Post #103 65
{ریکت}:

State و Props چی‌ان؟ فرقشون چیه؟

تصور کن یه کامپوننت داری به اسم UserCard. حالا سوال:

· اون اطلاعاتی که از بیرون بهش می‌دی → Props
· اون اطلاعاتی که خودش نگه می‌داره و تغییر می‌ده → State

مثال:

Props = اطلاعاتی که از بیرون میاد

Props= اجازه تغییرش نداری
function UserCard({ name, age }) {
  return (
    <div>
      <h3>{name}</h3>
      <p>{age} ساله</p>
    </div>
  );
}

// استفاده
<UserCard name="فاطمه" age={25} />

name و age دوتا props هستن که والد داده

UsetCard  فقط اونارو خونده

State = چیزی که خودت مدیریت می‌کنی

State مثل حالت داخلی خودته. می‌تونی تغییرش بدی و با تغییرش، UI دوباره رندر می‌شه.
function Counter() {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(count + 1)}>
      کلیک: {count}
    </button>
  );
}

count داخلیه
setCount تغییرش می‌ده
React دوباره رندر می‌کنه.


ارتباطشون چیه؟

State والد می‌تونه بشه Props فرزند!
function Parent() {
  const [name, setName] = useState("فاطمه");

  return <Child userName={name} />;
}

function Child({ userName }) {
  return <p>سلام {userName}</p>;
}

· name تو والد → State
· userName تو فرزند → Props

یعنی State یه جا زندگی می‌کنه، Props مسیر انتقالش به بقیه‌ست.

قانون طلایی

Props = ورودی
State = حافظه داخلی

هر چیزی که کاربر باهاش تعامل داره (تایپ، کلیک، انتخاب) → State
هر چیزی که از بالا میاد → Props


اشتباه رایج تازه‌کارها

تغییر مستقیم Props داخل کامپوننت
props.name = "نازی"; // ❌ هیچوقت!

اگه لازمه تغییر کنه، یا State بساز یا از والد بخواه تغییر بده.

هر وقت گیج شدی بپرس:
«این داده از کجا میاد؟»
اگه از بالا → Props
اگه خودش ساخته → State

همین یه سوال، 90%گیجی‌ها رو حل می‌کنه

@perfino_com
  • 👍 4
Post #102 63
📌 ترفند CSS: تایپوگرافی ریسپانسیو با clamp()

فراموش کن 5 تا media query برای سایز فونت بنویسی!

h1 {
font-size: clamp(1.5rem, 4vw, 3rem);
}

کمینه: 1.5rem
ایده‌آل: 4vw (با صفحه بزرگ می‌شه)
بیشینه: 3rem


یه خط، جای 5 تا مدیا کوئری

#Responsive

@perfino_cin
  • 🔥 3
  • 👍 1
Post #99 67
Debounce vs Throttle — دو ترفند نجات‌دهنده پرفورمنس

اگه مستقیم به scroll، resize یا input تابع سنگین وصل کردی، داری CPU کاربر رو می‌سوزونی! 🔥

اینا میان وسط:

🔹 Debounce → صبر کن کاربر دست از کار بکشه، بعد اجرا کن
🔹 Throttle → هر X میلی‌ثانیه یه بار اجرا کن، نه بیشتر


🧩Debounce
function debounce(fn, delay = 500) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
  };
}

// جستجوی زنده
input.addEventListener("input", debounce(e => {
  fetch(`/search?q=${e.target.value}`);
}, 600));

تا کاربر تایپ نکنه، درخواست نمی‌ره ✅
یعنی نه سرور درگیر می‌شه، نه UI لگ می‌زنه.



🧩 Throttle
function throttle(fn, limit = 200) {
  let last = 0;
  return (...args) => {
    const now = Date.now();
    if (now - last >= limit) {
      last = now;
      fn(...args);
    }
  };
}

// اسکرول
window.addEventListener("scroll", throttle(() => {
  console.log(window.scrollY);
}, 300));

هر ۳۰۰ms یه بار، نه بیشتر ✅
یعنی پرفورمنس عالی


🎯 کجا استفاده کنیم؟

جستجوی زنده Debounce
اعتبارسنجی فرم Debounce
رویداد scroll Throttle
رویداد resize Throttle

@perfino_com
  • ❤‍🔥 1
  • 👍 1
  • 🔥 1
Post #98 77
الان که تو مسیر یادگیری هستی عجله نکن که فقط پیش بری

کارفرما این •• تسلط •• ازت میخاد


@perfino_com
  • 👍 4
  • 🔥 1
Post #97 89

This post (sticker, poll or similar) has no web preview. Open in Telegram

  • 👍 2
  • 🔥 1
Post #96 107
شبکه خصوصی شخصی؛ دسترسی به سیستم‌های خونه از هر جای دنیا

تا حالا شده بیرون از خونه باشی و یه فایل فوری رو لپ‌تاپ یا سیستمت جا مونده باشه؟ یا بخوای از راه دور با ریموت دسکتاپ (RDP/SSH) به سیستمت دسترسی داشته باشی ولی IP ثابت نداشته باشی؟ ابزار Tailscale دقیقاً برای همین کاره؛ ساخت یه شبکه خصوصی و امن (Mesh VPN) بین تمام دستگاه‌های شخصی شما.

بدون نیاز به پورت‌فورواردینگ:
نیازی به داشتن آی‌پی استاتیک یا تغییر تنظیمات مودم ندارید؛ خودش فایروال و NAT رو دور می‌زنه.

ارتباط مستقیم و امن:
بر پایه پروتکل قدرتمند WireGuard ساخته شده و تمام ترافیک به صورت سرتاسری (End-to-End) رمزنگاری میشه.

مولتی‌پلتفرم واقعی:
از ویندوز، مک، لینوکس گرفته تا اندروید و iOS رو بدون دردسر داخل یک شبکه به هم وصل می‌کنه.

پلن رایگان:
برای استفاده شخصی کاملاً رایگانه و تا ۱۰۰ دستگاه رو پوشش میده.

اشتراک‌گذاری فایل و سرویس:
اشتراک آسان فایل (Taildrop) و دسترسی راحت به سرورهای خانگی یا NAS بدون افشای اون‌ها در اینترنت عمومی.

نکته مهم:

این ابزار یک وی‌پی‌ان سنتی برای وب‌گردی یا دور زدن فیلترینگ نیست؛ هدف اصلیش وصل کردن ایمن دستگاه‌های خودتون به همدیگه‌ست (مگر اینکه سرور شخصی خارج از کشور داشته باشید و اونو به عنوان Exit Node تنظیم کنید).



دریافت و استفاده:

نیازی به ابزارهای متفرقه نیست؛ کافیه برنامه رو از سایت رسمی tailscale.com یا استور گوشیتون دانلود کنید، با یک اکانت مشترک لاگین بشید و تمام دستگاه‌هاتون شبکه بشن.


@perfino_com
  • 👍 3
  • 🔥 1
Post #95 67

This post (sticker, poll or similar) has no web preview. Open in Telegram

  • ❤‍🔥 1
  • 👍 1
  • 👏 1
Post #93 73
  • 🔥 4
  • 👍 1
Older posts →

About this channel

How can I read @perfino_com without a Telegram account?
TGViewer shows the public web preview Telegram publishes for Perfino🌱: recent posts, photos, videos and the subscriber count, with no app, login or account.
How many subscribers does Perfino🌱 have?
Perfino🌱 (@perfino_com) has 64 subscribers on Telegram, refreshed roughly every 30 minutes.
Does Perfino🌱 know I viewed it here?
No. Public channel previews carry no viewer identity, and TGViewer has no accounts or tracking of what you look up.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →