# स्टेट प्रबंधन

> CrossFly का स्टेट पैटर्न — रिएक्टिव बाइंडिंग नहीं, मैन्युअल ViewModel + onUI + repaint।

Source: https://crossfly.dev/hi/docs/data-and-services/state-management — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# स्टेट प्रबंधन

अगर आप React/Flutter/Compose से आ रहे हैं, तो सबसे बड़े अंतर के लिए तैयार रहें: **यहाँ रिएक्टिव
डेटा-बाइंडिंग नहीं है**। कोई `useState`/`Observable`/`setState()` नहीं जो खुद-ब-खुद फिर से बनाता हो। मॉडल
**इंपरेटिव + स्पष्ट इनवैलिडेशन** है — इसका "क्यों"
[स्टेट और डेटा फ़्लो](/docs/concepts/state-and-data-flow) में है।

## पैटर्न
स्टेट आपके किसी ऑब्जेक्ट (एक ViewModel/सर्विस) के **साधारण फ़ील्ड्स** में रहता है। जब यह बदलता है, तो **आप विजेट
अपडेट करते हैं** और `repaint()` कॉल करते हैं — अगर यह किसी दूसरी थ्रेड से आया है, तो `Component.onUI(...)` के भीतर।
```java
class HomeVM {
   List<Cliente> clientes = new ArrayList<>();
}

public class TelaHome extends Window {
   private final HomeVM vm = new HomeVM();
   private ListView<Cliente> lista;

   @Override public void onShow() throws Exception {
      super.onShow();
      setLayout(new VerticalLayout());
      add(LAY_FILL, lista = new ListView<>());
      carregar();
   }

   private void carregar() {
      new Thread(() -> {
         List<Cliente> dados = repositorio.buscarTudo();   // भारी काम, background thread
         Component.onUI(() -> {                             // paint thread पर वापस
            vm.clientes = dados;
            lista.setItems(dados);                          // widget अपडेट करता है
            Component.repaint();                            // नया frame मांगता है
         });
      }).start();
   }
}
```

## क्षणिक स्टेट बनाम एप्लिकेशन स्टेट
| प्रकार | कहाँ रहता है | नेविगेशन के बाद बचता है? |
|---|---|---|
| **स्क्रीन-क्षणिक** | `Window` के फ़ील्ड्स | नहीं — स्क्रीन छोड़ते ही गायब |
| **एप्लिकेशन** | एक साझा singleton/सर्विस | हाँ — स्क्रीनों के बीच बना रहता है |

स्कोप के अनुसार चुनें: किसी खोज का फ़िल्टर क्षणिक है; लॉग-इन उपयोगकर्ता एप्लिकेशन-स्तर का है।

## अच्छी प्रथाएँ
- **हर स्क्रीन पर एक ViewModel** स्टेट और लॉजिक को केंद्रित करता है; `Window` सिर्फ़ UI ↔ VM को जोड़ती है।
- स्क्रीनों के बीच साझा स्टेट → **सर्विस/singleton**, बिखरे हुए static फ़ील्ड नहीं।
- बैकग्राउंड थ्रेड से विजेट छूने से पहले हमेशा `onUI(...)` के साथ UI पर लौटें।

## आम गलतियाँ
- यह उम्मीद करना कि मॉडल बदलने से UI खुद अपडेट हो जाएगी — **नहीं होती**; `setX(...)` + `repaint()` कॉल करें।
- ऐप स्टेट को `Window` के फ़ील्ड्स में रखना (नेविगेट करते ही खो जाता है)।

## यह भी देखें
- अवधारणा: [स्टेट और डेटा फ़्लो](/docs/concepts/state-and-data-flow) · [पेंट थ्रेड](/docs/concepts/the-paint-thread)
- [SQLite के साथ पर्सिस्टेंस](/docs/data-and-services/storage-sqlite) · [बैकग्राउंड में काम](/docs/data-and-services/background-work)
- ऐप आर्किटेक्चर: [best-practices](/docs/best-practices)
