useStoreValue

Subscribe to store changes and trigger component re-renders automatically

API Reference

Syntax

const state = useStoreValue(store, options?)

Parameters

  • store: ZenBox store instance
  • options (optional):
    • pick: Array of keys for selective subscription
    • deep: Enable deep equality checking for nested objects (default: false)

Returns

Current store state or selected fields when using the pick option.

Examples

Full Store Subscription

Subscribe to all store changes for complete reactivity:

import { createStore, useStoreValue } from "zenbox";

const userStore = createStore({
  name: "John",
  age: 30,
  email: "john@example.com",
});

function UserProfile() {
  const user = useStoreValue(userStore);

  return (
    <div>
      <h1>{user.name}</h1>
      <p>Age: {user.age}</p>
      <p>Email: {user.email}</p>
    </div>
  );
}

Selective Subscription

Optimize performance by subscribing only to the fields you need:

function UserName() {
  // Re-renders only when 'name' changes
  const { name } = useStoreValue(userStore, {
    pick: ["name"],
  });

  return <h1>{name}</h1>;
}

function UserContact() {
  // Re-renders only when 'name' or 'email' changes
  const { name, email } = useStoreValue(userStore, {
    pick: ["name", "email"],
  });

  return (
    <div>
      <p>Name: {name}</p>
      <p>Email: {email}</p>
    </div>
  );
}

Deep Comparison

For complex nested objects that require deep comparison:

const settingsStore = createStore({
  theme: {
    colors: { primary: "#blue", secondary: "#gray" },
    typography: { fontSize: 16, fontFamily: "Arial" },
  },
  preferences: {
    notifications: true,
    autoSave: false,
  },
});

function ThemeDisplay() {
  // Deep diffing for nested object changes
  const { theme } = useStoreValue(settingsStore, {
    pick: ["theme"],
    deep: true,
  });

  return (
    <div style={{ color: theme.colors.primary }}>
      Theme: {theme.colors.primary}
    </div>
  );
}

Best Practices

Use selective subscription for large stores

// Good: Only subscribe to needed fields
const { name, status } = useStoreValue(largeStore, {
  pick: ["name", "status"],
});

Avoid full subscription when you only need specific fields

// Inefficient: Subscribes to all changes
const store = useStoreValue(largeStore);
return <div>{store.name}</div>; // Only uses name

Prefer shallow watching for performance

// Default shallow comparison is usually sufficient
const user = useStoreValue(userStore);

Don't use deep watching unless necessary

// Expensive: Only use when you need deep object comparison
const data = useStoreValue(store, { deep: true });

Hook Comparison

HookPurposeRe-rendersBest For
useStoreValueFull store subscription✅ YesAll store data
usePickSelective field subscription✅ YesSpecific fields
useComputedDerived reactive values✅ YesCalculated data
useWatchSide effects on changes❌ NoLogging, APIs
  • usePick - Convenient shorthand for field selection
  • useComputed - Create derived reactive values
  • useWatch - Watch changes with side effects