Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/tim-smart/effect-atom/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The useAtomSubscribe hook subscribes to an atom’s changes and calls a callback function whenever the value updates. This is useful for side effects that need to react to atom changes without triggering component re-renders.

Signature

function useAtomSubscribe<A>(
  atom: Atom<A>,
  callback: (value: A) => void,
  options?: { readonly immediate?: boolean }
): void
atom
Atom<A>
required
The atom to subscribe to
callback
(value: A) => void
required
Function called whenever the atom’s value changes
options.immediate
boolean
If true, the callback is called immediately with the current value. Default: false

Behavior

  • Subscribes to the atom when the component mounts
  • Calls the callback function on every atom update
  • Unsubscribes automatically when the component unmounts
  • Does not trigger component re-renders
  • With immediate: true, calls the callback with the current value immediately

Usage

Log atom changes

import { Atom, useAtomSubscribe, useAtomSet } from "@effect-atom/atom-react"

const counterAtom = Atom.make(0)

function CounterWithLogging() {
  const setCount = useAtomSet(counterAtom)
  
  // Log every change to the counter
  useAtomSubscribe(counterAtom, (value) => {
    console.log("Counter changed to:", value)
  })
  
  return (
    <button onClick={() => setCount(c => c + 1)}>
      Increment
    </button>
  )
}

Sync to localStorage

const preferencesAtom = Atom.make({
  theme: "light",
  language: "en"
})

function PreferencesSync() {
  // Sync preferences to localStorage on every change
  useAtomSubscribe(
    preferencesAtom,
    (prefs) => {
      localStorage.setItem("preferences", JSON.stringify(prefs))
    },
    { immediate: true } // Save initial value too
  )
  
  return null
}

Track analytics events

const pageViewAtom = Atom.make({ page: "/", timestamp: Date.now() })

function AnalyticsTracker() {
  useAtomSubscribe(pageViewAtom, (view) => {
    // Send analytics event
    analytics.track("page_view", {
      page: view.page,
      timestamp: view.timestamp
    })
  })
  
  return null
}

Trigger notifications

const notificationAtom = Atom.make<string | null>(null)

function NotificationListener() {
  useAtomSubscribe(notificationAtom, (message) => {
    if (message !== null) {
      // Show a toast notification
      toast.show(message)
    }
  })
  
  return null
}

Immediate callback

const userAtom = Atom.make({ id: 1, name: "Alice" })

function UserLogger() {
  // Log the current value immediately, then on every change
  useAtomSubscribe(
    userAtom,
    (user) => {
      console.log("Current user:", user)
    },
    { immediate: true }
  )
  
  return null
}

Multiple subscriptions

function MultipleTrackers() {
  // Track different aspects separately
  useAtomSubscribe(cartAtom, (cart) => {
    console.log("Cart items:", cart.length)
  })
  
  useAtomSubscribe(cartAtom, (cart) => {
    const total = cart.reduce((sum, item) => sum + item.price, 0)
    analytics.track("cart_total", { total })
  })
  
  return null
}

Performance considerations

useAtomSubscribe does not cause component re-renders. Use it for side effects that don’t need to update the UI.
Avoid expensive operations in the callback function. Consider debouncing or throttling if the atom updates frequently.

Comparison with useAtomValue

HookRe-renders componentUse case
useAtomValueYesDisplay atom value in UI
useAtomSubscribeNoSide effects without re-renders

Cleanup

The subscription is automatically cleaned up when the component unmounts. If you need manual control, use Registry.subscribe directly in a useEffect.

Build docs developers (and LLMs) love