CxJS

PrivateStore

import { PrivateStore } from 'cx/widgets'; Copied

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

<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>
Global Store
 
 
Private Store A
 
 
Private Store B
 
 

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.

<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>
Global Store
 
Private Store A
 
 
Private Store B
 
 

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.

Warning

Detached mode may break some advanced features that depend on shared context, such as form validation.

Configuration

PropertyTypeDescription
dataobjectObject mapping internal binding names to values from the parent store.
detachedbooleanRender in a separate render loop for performance. Breaks context-dependent features.
deferredUntilIdlebooleanDefer rendering until the browser is idle.
idleTimeoutnumberTime limit in milliseconds the browser can defer rendering.
immediatebooleanDisable batching of updates.