Update README.md

This commit is contained in:
2026-06-07 06:26:57 +00:00
parent d0e0d25fe5
commit 8aebf260e2

368
README.md
View File

@@ -1,2 +1,368 @@
# 06-compose-state
# 1. مشکل از کجا شروع شد؟
قبل از Jetpack Compose در اندروید، وقتی داده‌ای در برنامه تغییر می‌کرد باید **خودمان دستی UI را آپدیت می‌کردیم**.
مثال:
کاربر روی دکمه افزایش کلیک می‌کند → مقدار عدد تغییر می‌کند → باید TextView را هم تغییر دهیم.
در View های قدیمی:
```kotlin
count++
textView.text = count.toString()
```
یعنی برنامه‌نویس **باید یادش بماند UI را هم آپدیت کند**.
مشکل‌ها:
- ممکن است فراموش کنیم UI را آپدیت کنیم
- کدها پیچیده می‌شوند
- نگهداری سخت می‌شود
---
# 2. راه‌حل Compose چیست؟
در Compose یک قانون مهم داریم:
**UI باید تابعی از State باشد**
یعنی:
```
UI = f(state)
```
اگر state تغییر کند → UI خودش دوباره ساخته می‌شود.
به این فرایند می‌گوییم:
**Recomposition**
---
# 3. State چیست؟
State یعنی:
**داده‌ای که اگر تغییر کند، UI باید تغییر کند.**
مثال‌ها:
- مقدار counter
- متن داخل TextField
- وضعیت لودینگ
- لیست پیام‌ها
- وضعیت لاگین کاربر
مثال ساده:
```kotlin
var count = 0
```
اگر مقدار `count` تغییر کند، UI باید تغییر کند.
اما Compose از تغییر این متغیر خبر ندارد.
پس باید از **State مخصوص Compose** استفاده کنیم.
---
# 4. mutableStateOf چیست؟
برای اینکه Compose بفهمد داده تغییر کرده باید از **State Object** استفاده کنیم.
یکی از مهم‌ترین آن‌ها:
```
mutableStateOf
```
مثال:
```kotlin
var count = mutableStateOf(0)
```
اینجا count یک **State** است.
برای دسترسی به مقدار:
```
count.value
```
مثال:
```kotlin
count.value++
```
وقتی مقدار تغییر کند:
Compose متوجه می‌شود → UI دوباره ساخته می‌شود.
---
# 5. استفاده از State در Compose
یک مثال ساده Counter:
```kotlin
@Composable
fun CounterScreen() {
var count = remember { mutableStateOf(0) }
Column {
Text(text = "Count: ${count.value}")
Button(onClick = {
count.value++
}) {
Text("Increase")
}
}
}
```
اتفاقی که می‌افتد:
1⃣ صفحه ساخته می‌شود
2⃣ مقدار count = 0
3⃣ Text مقدار 0 را نشان می‌دهد
4⃣ کاربر دکمه را می‌زند
5⃣ مقدار count تغییر می‌کند
6⃣ Compose تشخیص می‌دهد state تغییر کرده
7⃣ UI دوباره اجرا می‌شود
این فرایند همان **Recomposition** است.
---
# 6. Recomposition چیست؟
**Recomposition یعنی اجرای دوباره Composable ها وقتی State تغییر می‌کند.**
در مثال قبل:
وقتی:
```
count.value++
```
اجرا می‌شود
Compose:
- متوجه تغییر state می‌شود
- Composable مربوطه را دوباره اجرا می‌کند
- UI جدید رسم می‌شود
نکته مهم:
Compose **کل صفحه را دوباره نمی‌سازد**
فقط بخش‌هایی که نیاز دارند دوباره اجرا می‌شوند.
---
# 7. remember چیست؟
یک مشکل مهم وجود دارد.
اگر این کد را بنویسیم:
```kotlin
var count = mutableStateOf(0)
```
در هر Recomposition مقدار دوباره **0 می‌شود**.
چرا؟
چون تابع دوباره اجرا می‌شود.
برای حل این مشکل از:
```
remember
```
استفاده می‌کنیم.
```kotlin
var count = remember { mutableStateOf(0) }
```
remember باعث می‌شود:
✅ مقدار بین recomposition ها حفظ شود.
---
# 8. روش بهتر: by delegation
نوشتن `.value` کمی آزاردهنده است.
روش بهتر:
```kotlin
var count by remember { mutableStateOf(0) }
```
حالا می‌توانیم مستقیم استفاده کنیم:
```kotlin
count++
```
مثال کامل:
```kotlin
@Composable
fun CounterScreen() {
var count by remember { mutableStateOf(0) }
Column {
Text(text = "Count: $count")
Button(onClick = {
count++
}) {
Text("Increase")
}
}
}
```
---
# 9. جریان کامل اتفاقات
مراحل اجرای برنامه:
1⃣ Composable اجرا می‌شود
2⃣ State ساخته می‌شود
3⃣ UI بر اساس State ساخته می‌شود
وقتی کاربر دکمه را می‌زند:
4⃣ State تغییر می‌کند
5⃣ Compose تغییر را تشخیص می‌دهد
6⃣ Recomposition انجام می‌شود
7⃣ UI جدید ساخته می‌شود
---
# 10. مثال Counter کامل
```kotlin
@Composable
fun CounterScreen() {
var count by remember { mutableStateOf(0) }
Column {
Text(
text = "Count: $count",
fontSize = 30.sp
)
Button(
onClick = { count++ }
) {
Text("Increase")
}
Button(
onClick = { count-- }
) {
Text("Decrease")
}
}
}
```
---
# 11. نکات مهم
✅ State داده‌ای است که UI به آن وابسته است.
✅ وقتی State تغییر کند → Recomposition اتفاق می‌افتد.
✅ برای تعریف State از `mutableStateOf` استفاده می‌کنیم.
✅ برای حفظ مقدار در Recomposition از `remember` استفاده می‌کنیم.
✅ بهتر است از `by` استفاده کنیم تا `.value` حذف شود.
---
# 12. تمرین برای دانشجویان
1⃣ یک Counter بسازید که دکمه‌های زیر داشته باشد:
- Increase
- Decrease
- Reset
2⃣ اگر مقدار Counter به **10 رسید** یک متن نمایش دهید:
```
Maximum reached!
```
3⃣ اگر مقدار Counter **منفی شد** رنگ متن قرمز شود.
---
# 13. چالش فکری
اگر به جای State این کد را بنویسیم:
```kotlin
var count = 0
```
و در Button مقدار را زیاد کنیم:
```
count++
```
آیا UI تغییر می‌کند؟
چرا؟
---
پاسخ:
خیر. چون Compose از تغییر این متغیر خبر ندارد. بنابراین Recomposition اتفاق نمی‌افتد.
---
# جمع‌بندی
مهم‌ترین مفاهیم Compose:
- State → داده قابل تغییر UI
- mutableStateOf → ساخت state
- remember → نگهداری مقدار در recomposition
- Recomposition → اجرای دوباره UI بعد از تغییر state
قانون اصلی Compose:
**UI تابعی از State است.**