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

> कोई reactive binding नहीं — स्टेट fields/ViewModel में, View हाथ से स्टेट→कॉम्पोनेंट्स अनुवादित करती है।

Source: https://crossfly.dev/hi/docs/learn/managing-state — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

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

> **आप क्या सीखेंगे:** CrossFly का स्टेट मॉडल — जहाँ Flutter/React से आने वालों को **भूलना** पड़ता है।
> **पूर्वापेक्षाएँ:** [इनपुट संभालना](/docs/learn/handling-input)।

## संपूर्ण उदाहरण (कॉपी करें, पेस्ट करें और चलाएँ)
मैन्युअल `observe(Runnable)` वाली एक हल्की ViewModel (`TarefaVM`) (कोई reactive binding नहीं है): जब स्टेट
बदलता है तब View कॉम्पोनेंट्स को पुन:भरती है। एक बटन कार्य जोड़ता है और सूची फिर से render होती है। जैसा है वैसा ही compile होता है।
```java
package com.exemplo;

import java.util.*;
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;

public class MainWindow extends Window
{
   private final TarefaVM vm = new TarefaVM();
   private final Component listaBox = new Component();
   private int contador = 1;

   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      Button add = new Button("Adicionar tarefa");
      add.onAction(c -> vm.adicionar(new Tarefa("Tarefa " + (contador++))));
      add(LAY_AUTO, add);

      listaBox.setLayout(new VerticalLayout());
      add(LAY_FILL, listaBox);

      vm.observe(this::renderizarLista);   // स्थिति बदलने पर फिर से भरता है
      renderizarLista();
   }

   private void renderizarLista()
   {
      listaBox.removeAll();
      for (Tarefa t : vm.tarefas) listaBox.add(LAY_AUTO, new Label(t.titulo));
      listaBox.setValidLayout(false);      // आकार बदल गया
      Component.repaint();
   }
}

class Tarefa
{
   final String titulo;
   Tarefa(String titulo) { this.titulo = titulo; }
}

class TarefaVM
{
   private Runnable onChange;
   public List<Tarefa> tarefas = new ArrayList<>();

   public void observe(Runnable r) { this.onChange = r; }
   private void mudou() { if (onChange != null) onChange.run(); }

   public void adicionar(Tarefa t)
   {
      var novo = new ArrayList<>(tarefas); novo.add(t);
      tarefas = novo;
      mudou();                             // View को सूचित करता है (paint thread पर)
   }
}
```
> नीचे के अंश **केवल मूल भाग** दिखाते हैं (जो `onShow()` के भीतर जाता है)। चलाने के लिए, उन्हें ऊपर के `MainWindow` ढाँचे में रखें।

## कोई reactive binding नहीं है
मॉडल बदलने से UI स्वयं अपडेट **नहीं** होती। स्टेट fields में रहता है (या एक हल्की **ViewModel** में), और
View **स्टेट → कॉम्पोनेंट्स को मैन्युअल रूप से अनुवादित करती है**, `repaint()` को कॉल करते हुए (और यदि
आकार बदला हो तो `setValidLayout(false)`)।

## `observe` के साथ एक हल्की ViewModel
```java
public class TarefaVM {
   private Runnable onChange;
   public List<Tarefa> tarefas = List.of();
   public void observe(Runnable r) { this.onChange = r; }
   private void mudou() { if (onChange != null) onChange.run(); }

   public void adicionar(Tarefa t) {
      var novo = new ArrayList<>(tarefas); novo.add(t);
      tarefas = novo;
      mudou();                    // View को सूचित करता है (paint thread पर)
   }
}
```

## View प्रतिक्रिया देती है
```java
@Override public void onShow() throws Exception {
   super.onShow();
   // … UI बनाता है …
   vm.observe(this::renderizarLista);   // स्थिति बदलने पर घटकों को फिर से भरता है
   vm.carregar();                       // लोडिंग ट्रिगर करता है (बैकग्राउंड में — अगला अध्याय)
}

private void renderizarLista() {
   listaBox.removeAll();
   for (Tarefa t : vm.tarefas) { CardTarefa card = new CardTarefa(); listaBox.add(LAY_AUTO, card); card.bind(t); }
   listaBox.setValidLayout(false);
   Component.repaint();
}
```
> नियम: म्यूटेशन और नोटिफिकेशन **हमेशा paint thread पर**। यदि डेटा पृष्ठभूमि से आया, तो View जो स्टेट पढ़ती है
> उसे छूने से पहले `Component.onUI(...)` में प्रवेश करें (अगला अध्याय देखें)।

## इस चरण में क्या बनाया जाता है
**`TarefaVM`** के साथ स्क्रीन जो स्टेट बदलने पर फिर से render होती है।

## पुनरावलोकन
कोई reactive नहीं: स्टेट fields/ViewModel में; View `repaint()` के साथ स्टेट→कॉम्पोनेंट्स अनुवादित करती है; एक
मैन्युअल `observe(Runnable)` binding की जगह लेता है।

## अगले कदम
→ [डेटा लोड करना](/docs/learn/loading-data)

## यह भी देखें
- अवधारणा: [स्टेट और डेटा प्रवाह](/docs/concepts/state-and-data-flow) · [ऐप आर्किटेक्चर](/docs/best-practices/arquitetura-de-app)
