Foad Labs
82 subscribers
46 photos
2 videos
2 files
45 links
Building modern web experiences.
React • Next.js • TypeScript

🪐 DM For collaborates: @foad_ebrahiml
🌐 Personal website: https://foad-ebrahimi.ir
Download Telegram
🤔 این دوتا یه مسئله رو حل میکنن ولی فلسفه‌شون کاملاً فرق داره.
🔄 Redux Toolkit
هنوز به slice و reducer نیاز داره. حتی با RTK، ساختار قابل پیش‌بینیه ولی حجیم‌تره.
📦 Zustand
با یه تابع create، کل store رو میسازه، بدون Provider اجباری، بدون boilerplate اضافه.
⚡️ از نظر re-render هم هر دو با selector کار میکنن، پس اونجا فرقی نیست.
🎯 سوال اصلی اینه : تیم چندنفره‌این و به قوانین سخت‌گیرانه و DevTools پیشرفته نیاز دارین؟ ← Redux Toolkit 🛠️
پروژۀ کوچیک تا متوسطه و سرعت توسعه اولویته؟ ← Zustand 🚀

منابع :
🔗 Zustand — Getting Started
🔗 Redux Toolkit — Quick Start
🔥2
⚙️ اکثر پیاده‌سازی‌های useDebounce که توی پروژه‌های مختلف دیدم، یه مشکل مشترک دارن :
کلین‌آپ ندارن!
بدون cleanup، هر بار که ورودی عوض میشه، تایمر قبلی هنوز فعاله و ممکنه callback قدیمی با state قدیمی اجرا بشه (stale closure).

دو نکته مهم :

همیشه generic تعریفش کنید تا برای هر نوع داده قابل استفاده مجدد باشه
delay
رو حتما توی dependency array بذارید وگرنه اگه تغییر کنه، hook متوجه نمیشه

منبع رسمی
👌2
🔴 چالش امشب
این کد یه infinite loop تولید میکنه خودتون دلیلش رو پیدا کنین

15 دقیقه دیگه جوابش رو میزارم همراه با راه‌حل

#Labs_Challenge
🔥1
جواب :
options
هر بار توی کامپوننت از نو ساخته میشه (یه object literal جدید)، پس رفرنسش هر رندر عوض میشه، useEffect دوباره اجرا میشه، یه رندر جدید اتفاق میفته... و این چرخه هیچوقت تموم نمیشه.
🟠 برای حل این مشکل سه تا راه‌حل داریم که توی تصویر ذکر شده

🟢 بهترین راه‌حل به context و منطق کامپوننتتون ستگی داره. اگه options ثابته، گزینه ۳ بهترینه چون اصلا هیچ هزینه‌ای نداره.
🔥1
مرسی از همه دوستان که توی چالش امشب شرکت کردن و نظرات خودشونو درمیون گذاشتن
فردا کلی محتوا و در آخرشب هم چالش داریم

شبتون پر از ایده‌های میلیون دلاری 😁❤️
🔥1
امروز رو اختصاص میدیم به خود Next.js و rendering strategies توی اون

مثل همیشه خوشحال میشیم نظرات و فکرهایی که به ذهنتون میاد رو با بقیه به اشتراک بزارین تا کنار همدیگه رشد کنیم ❤️

برو بریم
🔥1
⁉️ یه سوال که توی هر مصاحبه فرانت‌اند پرسیده میشه

فرق SSR، SSG و ISR چیه؟

بذارین خیلی ساده توضیح بدم

1️⃣ SSG — Static Site Generation
صفحه موقع build یه بار ساخته میشه و همون سرو میشه به همه. سریع‌ترین حالت ممکنه چون فایل آماده‌ست.
🟢 مناسب برای : صفحه About، بلاگ، صفحات ثابت

2️⃣ SSR — Server-Side Rendering
هر بار که کاربر درخواست میده، سرور HTML رو از نو میسازه.
🟢 مناسب برای : داشبورد، صفحاتی که داده‌شون هر لحظه عوض میشه

3️⃣ ISR — Incremental Static Regeneration
بین دوتای قبلی قرار میگیره. HTML استاتیکه، ولی بعد از یه بازه زمانی مشخص پشت صحنه دوباره ساخته میشه — بدون اینکه کاربر منتظر بمونه.
// هر یک ساعت یه بار regenerate میشه
export const revalidate = 3600;

🟢 مناسب برای : صفحه محصولات، اخبار، هر چیزی که داده‌ش تغییر میکنه ولی real-time نیست

انتخاب درست بین این سه، مستقیم روی TTFB (time to first byte) و هزینه سرور تاثیر میذاره.

منبع رسمی :
Fetching Data
Rendering Strategies
2
⚡️ Server Components vs Client Components
کجا مرز رو بکشیم؟ 🤔

یکی از رایج‌ترین اشتباه‌ها توی Next.js اینه که use client رو بالای کامپوننت‌هایی میذارن که اصلا نیازی ندارن.

قانون ساده 📜 :

Server Component
بمونه اگه :

- فقط داده نمایش میده
- به API یا دیتابیس وصله
- هیچ تعاملی با کاربر نداره (کلیک، فرم، state)

Client Component
بشه اگه :

- از useState یا useEffect استفاده میکنه
- به event listener نیاز داره
- از browser API استفاده میکنه

🛑 اشتباه رایج : 'use client' گذاشتن روی layout یا page اصلی. این یعنی کل درخت کامپوننت client-side میشه و مزیت Server Components از بین میره.

منبع رسمی :
Server and Client Components
👍1
⏱️ صفحمون TTFB بالای 2 ثانیه داشت اما Streaming SSR رو حل کرد
❗️ مشکل اینجا بود که صفحه منتظر میموند تا همه دیتاها از سه تا endpoint جدا برگردن، بعد HTML رو میفرستاد. کاربر تا اون موقع فقط یه صفحه سفید میدید.

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

درخواست کاربر
↓ fetchUser() → 300ms
↓ fetchPosts() → 500ms
↓ fetchComments() → 2000ms 😬
↓ HTML آماده میشه و میره سمت کاربر


کاربر ۲.۸ ثانیه صبر میکنه تا اولین pixel ببینه.

🟢 راه‌حل : هر کامپوننت داده خودش رو مستقل fetch کنه (عکس ضمیمه شده)

الان timeline اینشکلیه :
درخواست کاربر
↓ همه fetchها موازی شروع میشن
↓ UserCard → 300ms فوری نمایش
↓ Posts → 500ms skeleton، بعد محتوا
↓ Comments → 2000ms skeleton، بعد محتوا


کاربر بعد از ۳۰۰ms یه صفحه معنادار میبینه، نه ۲.۸ ثانیه صفحه سفید، تفاوت رو دیدین ؟

⚠️ یه نکته مهم :
loading.tsx توی Next.js fallback کل route رو مدیریت میکنه، ولی Suspense بهتون کنترل دقیق‌تر میده — میتونید بخش‌های مختلف یه صفحه رو جداگانه هندل کنین

منبع رسمی :
Fetching Data#Streaming
Granular streaming with Suspense
Streaming
2
🔴 چالش شب — Next.js


🟠 چالش اصلاح میشه
Foad Labs
🔴 چالش شب — Next.js 🟠 چالش اصلاح میشه
من معذرت میخام دوستان کانتکست چالش اشتباه گذاشته شده
اصلاح شدش رو براتون میزارم امشب و تا فردا مثل همیشه نظراتتون رو بگین و شرکت کنین توی چالش ❤️
1
فقط کافیه به چیزایی که بهتون توصیه میکنه ابزار لایت‌هوس و قوانین سخت گیرانه گوگل آشنا باشین
به همین راحتی میتونین سایت خودتون و هر پروژه ای که دارین رو بهتر کنین
تارگت 100 مون زده شد
🗣 یک باور غلط بین برنامه‌نویس‌ها: وردپرس کلا داغونه و نمیشه بهینه‌ش کرد!
امروز توی گروه این جمله رو شنیدم که کدهای وردپرس از ریشه غیربهینه‌ست و برنامه‌نویسای غیر وردپرسی اصلا حاضر نیستن روش کار کنن!
خواستم چند تا نکته رو دوستانه باهاتون در میون بذارم :

اول از همه : وردپرس قرار نیست یک فریمورک مینیمال مثل Laravel باشه. وردپرس یک پلتفرمه که باید نیازهای ۴۳٪ از کل وب‌سایت‌های دنیا رو با هزاران افزونه مختلف برآورده کنه. این یعنی سربار (Overhead) بخشی از ذاتشه، نه ضعف کدنویسی!
دوم : بهینه‌سازی وردپرس اصلا به معنی دستکاری کدهای core اون نیست هنر یک وردپرس‌کار حرفه‌ای اینه که بدونه چطور با کشینگ (Redis)، بهینه‌سازی دیتابیس و معماری درست، سایتی رو بالا بیاره که از هر سایت کاستومی سریع‌تر باشه.
سوم : بله، ممکنه خیلی از برنامه‌نویس‌ها حوصله سروکله زدن با Hookها و ساختار قدیمی وردپرس رو نداشته باشن و این حقشونه. اما اینکه بگیم کدهاش از ریشه داغونه انصاف فنی نیست. هسته وردپرس مدام در حال آپدیت، تطبیق با PHP 8+ و استفاده از React در ادیتوره.

🎯 خلاصه کلام : ابزارها رو نباید با هم مقایسه کرد. شما با پیچ‌ گوشتی نمیتونی میخ بکوبی
وردپرس برای سرعت توسعه، اکوسیستم عظیم و مدیریت محتوا بی‌نظیره. اگر جایی کندیه، معمولا مشکل از نحوه پیاده‌سازی ماست، نه خود ابزار.

شما چطور؟ تا حالا شده به خاطر ساختار وردپرس کلافه بشین یا برعکس، از سرعت توسعه‌اش شگفت‌زده بشین برامون بنویسید.
👍1
Please open Telegram to view this post
VIEW IN TELEGRAM
2
Foad Labs
🔴 چالش شب — Next.js 🟠 چالش اصلاح میشه
🔴 چالش امروز — Next.js

کد توی تصویر ضمیمه شده رو ببینین

سوال : توی این کد چند تا UserCard رندر میشه و کدوماشون Server Component هستن؟

⚠️ قبل از جواب دادن، این سه گزینه رو در نظر بگیرین

الف) هر دو Server Component هستن
ب) اولی Server، دومی Client میشه چون داخل یه Client Component ایمپورت شده
ج) هر دو Client Component میشن

جوابتون همراه با چرا و همینطور راه‌حلتون رو بگین
📝 Commit message
خوب چطوریه؟
اگه توی git log خودتون این رو میبینین
fix bug
update
asdf
final version
FINAL version 2

بدونین که پخت و پز کردین ولی نه به سبک خفنش 😁😐

💥 Conventional Commits
یه استاندارد سادست که خوندن تاریخچه رو راحت میکنه :

# ساختار
<type>(<scope>): <description>

# مثال‌های واقعی
feat(auth): add Google OAuth login
fix(cart): prevent duplicate items on fast click
refactor(api): extract fetch logic to custom hook
perf(images): enable lazy loading for product gallery
docs(readme): update local setup instructions
chore(deps): upgrade React to v19


👍🏻 تایپ های رایجی که میتونین استفاده کنین =>
feat → feature جدید
fix → رفع باگ
refactor → بازنویسی بدون تغییر رفتار
perf → بهینه‌سازی
chore → کارهای جانبی (deps, config)

👇🏻 یه قانون ساده برای نوشتن description :
جمله رو با فعل امری شروع کنین — نه "added login" بلکه "add login". انگار دارید به کد دستور میدید چیکار کنه.

منبع رسمی :
Conventional Commits
🔀 یه چیزی که توی اکثر تیم‌ها غلط انجام میشه :
همه روی برنچ main کار میکنن
یه نفر یه چیزی push میکنه، نفر بعدی conflict میگیره، یه ساعت وقت تلف میشه برای چیزی که اصلا نباید اتفاق میفتاد

یه workflow ساده که این مشکل رو حل میکنه :

# ۱. برای هر feature یه branch جدا
git checkout -b feature/user-authentication

# ۲. commitهای کوچیک و معنادار
git commit -m "feat: add login form validation"
git commit -m "feat: integrate auth API"
git commit -m "fix: handle expired token error"

# ۳. قبل از PR، rebase کنید نه merge
git fetch origin
git rebase origin/main



چرا rebase به‌جای merge؟

#  merge — تاریخچه پاک میشه
git merge main
# نتیجه: یه merge commit اضافه + تاریخچه غیرخطی

# rebase — تاریخچه تمیز میمونه
git rebase origin/main
# نتیجه: انگار از همین لحظه branch زدید


history
تمیز یعنی git log خوندنی، git bisect کارآمد، و debug سریع‌تر.

منبع رسمی :
git
1
🌿 Branch naming
یه چیز کوچیک که کار تیم رو راحت میکنه
وقتی توی یه تیم کار میکنین و ۱۰ تا branch دارید، اگه اسم‌گذاری استاندارد نباشه :

git branch
# خروجی:
foad-changes
new-feature
fix
test2
modal-thing-foad

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

یه convention ساده :

# feature جدید
feature/user-profile-page
feature/add-payment-gateway

# رفع باگ
fix/cart-total-calculation
fix/mobile-nav-overflow

# بهینه‌سازی
perf/optimize-image-loading

# hotfix روی production
hotfix/critical-auth-bypass


یه قدم جلوتر — شماره تیکت رو هم اضافه کنین :

feature/AUTH-142-google-oauth
fix/CART-89-duplicate-items


حالا هر کسی branch رو میبینه، میدونه کجا باید بره برای context بیشتر.
1
یه چیزی که توی اکثر پروژه‌ها میبینم error handling اصلا وجود نداره — یا اگه هست، اینشکلیه :

try {
const data = await fetchUser(id);
setUser(data);
} catch (e) {
console.log(e); // 👈 و تموم
}


کاربر یه صفحه سفید میبینه، هیچکس نمیدونه چی شد، و debug کردن کابوس میشه
اول باید error type ها رو از هم جدا کنین =>
⭕️ ( عکس ضمیمه شده اول )

حالا توی fetch wrapper اینا رو handle میکنیم
⭕️ ( عکس ضمیمه شده دوم )

و توی کامپوننت، هر نوع خطا رو جداگانه handle میکنیم =>
⭕️ ( عکس ضمیمه شده سوم )

کاربر همیشه میدونه چی شده — نه صفحه سفید، نه پیام عمومی بی‌معنی.

منبع رسمی :
Using_Fetch