# PrivateStore

```ts
import { PrivateStore } from 'cx/widgets';
```



PrivateStore (also known as Restate) creates a separate, isolated data store for a part of the widget tree. This enables some parts of the application to behave independently from the rest.

## Example

```tsx
import { createModel } from "cx/data";
import { PrivateStore, Slider } from "cx/widgets";

interface PageModel {
  value: number;
}

const m = createModel<PageModel>();

export default (
  <div>
    <div class="text-sm font-medium leading-none mb-2">Global Store</div>
    <Slider value={m.value} />
    <Slider value={m.value} />

    <PrivateStore>
      <div class="text-sm font-medium leading-none mt-4 mb-2">
        Private Store A
      </div>
      <Slider value={m.value} />
      <Slider value={m.value} />
    </PrivateStore>

    <PrivateStore>
      <div class="text-sm font-medium leading-none mt-4 mb-2">
        Private Store B
      </div>
      <Slider value={m.value} />
      <Slider value={m.value} />
    </PrivateStore>
  </div>
);

```

Each PrivateStore has its own isolated data. Sliders within the same store share the same value, but don't affect sliders in other stores.

## Lifespan

Private stores have the lifespan of the PrivateStore component. When a PrivateStore is destroyed, its data is lost. If you navigate away and come back, only sliders in the global store will retain their values.

## Sharing Data

Data shared between the parent store and the private store must be explicitly defined with the `data` property. Bindings create two-way data flow, while expressions and computables are read-only.

```tsx
import { createModel } from "cx/data";
import { LabelsTopLayout } from "cx/ui";
import { PrivateStore, Slider } from "cx/widgets";

interface PageModel {
  slider: number;
}

const m = createModel<PageModel>();

interface PrivateModel {
  globalValue: number;
  localValue: number;
}

const mPrivate = createModel<PrivateModel>();

export default (
  <div>
    <div class="text-sm font-medium leading-none mb-2">Global Store</div>
    <Slider value={m.slider} />

    <PrivateStore data={{ globalValue: m.slider }}>
      <div class="text-sm font-medium leading-none mt-4 mb-2">
        Private Store A
      </div>
      <LabelsTopLayout>
        <Slider value={mPrivate.globalValue} label="Shared" />
        <Slider value={mPrivate.localValue} label="Private" />
      </LabelsTopLayout>
    </PrivateStore>

    <PrivateStore data={{ globalValue: m.slider }}>
      <div class="text-sm font-medium leading-none mt-4 mb-2">
        Private Store B
      </div>
      <LabelsTopLayout>
        <Slider value={mPrivate.globalValue} label="Shared" />
        <Slider value={mPrivate.localValue} label="Private" />
      </LabelsTopLayout>
    </PrivateStore>
  </div>
);

```

## Performance

PrivateStore can improve performance through:

- **Detached rendering** - Use `detached` to render the subtree in its own render loop. Changes inside won't trigger the main render loop and vice versa.
- **Deferred rendering** - Use `deferredUntilIdle` to defer rendering until the browser is idle, useful for heavy content.

Heavy charts or tables can be wrapped in a detached PrivateStore to prevent them from re-rendering on every store change.

<Note type="warning">
  Detached mode may break some advanced features that depend on shared context,
  such as form validation.
</Note>

## Configuration

| Property            | Type      | Description                                                                          |
| ------------------- | --------- | ------------------------------------------------------------------------------------ |
| `data`              | `object`  | Object mapping internal binding names to values from the parent store.               |
| `detached`          | `boolean` | Render in a separate render loop for performance. Breaks context-dependent features. |
| `deferredUntilIdle` | `boolean` | Defer rendering until the browser is idle.                                           |
| `idleTimeout`       | `number`  | Time limit in milliseconds the browser can defer rendering.                          |
| `immediate`         | `boolean` | Disable batching of updates.                                                         |