DocsBlog
  • 1.1.2

  • light

    dark

    system

    Switch mode
  • Cerberus

    Acheron

    Elysium

Get Started
Components
Data Grid
Signals
Styling
Theming

Get Started

OverviewReactivityData FetchingStores

Primitives

createSignalcreateQuerycreateMutationcreateComputedcreateEffectcreateStoreContextbatch

Hooks

useQueryuseMutationuseReaduseSignal

Components

ReactiveText

On this page

  • Edit this page on Github

Using Signals

Learn how to use fine-grained signals in React.

  • source
import { useSignal } from '@cerberus/signals'

Usage

When you want to create a signal within a component context.

There are two ways to read a global signal within a component:

  1. ReactiveText (recommended) for fine-grained reactivity
  2. Calling the accessor within the JSX

Basic State

useSignal works just like createSignal on a local component scale.

Reading State

There are two ways to read the signal value based on your preferred method:

  1. Using the first value: the latest accessor result
  2. Using the third value: the pure accessor function

Both options are valid and more performant than native React state. However, only the pure accessor can be passed into ReactiveText.

Setting State

With Cerberus Signals, how you set the state no longer matters. You are free to use mutation or immutability. Both results will yield the same high performant and reliable reactivity.

The second value of the Tuple is the Setter function.

The setter API is the exact same as the createSignal Setter and accepts any type of setting value or callback.

API

useSignal accepts the following options:

ParamsRequiredDescription
initialValuefalseThe initial value to set for the accessor.

Return

useSignal returns a SignalTuple<T> Array of the following values:

IndexTypeDescription
0TThe latest value of the accessor.
1Setter<T>A function to update the signal value.
2Accessor<T>A function that returns the latest value when called.
Copy
'use client'

import { HStack } from '@/styled-system/jsx'
import { Button, Text } from '@cerberus/react'
import { ReactiveText, createSignal, useSignal } from '@cerberus/signals'

function createDemoStore() {
  const [renderCount, setRenderCount] = createSignal<number>(0)
  return { renderCount, setRenderCount }
}

export function UseDemo() {
  const store = createDemoStore()
  const [count, setCount, getCount] = useSignal<number>(0)

  const increment = () => setCount(count + 1)

  store.setRenderCount(store.renderCount() + 1)

  return (
    <HStack justify="space-between" w="3/4">
      <HStack gap="md" w="full">
        <Button onClick={increment}>Increment</Button>
        <Text>{count}</Text>
        <ReactiveText data={getCount} />
      </HStack>

      <HStack gap="md" w="full">
        <Text>Render Count:</Text>
        <ReactiveText data={store.renderCount} />
      </HStack>
    </HStack>
  )
}
Copy
'use client'

import { HStack } from '@/styled-system/jsx'
import { Button, Text } from '@cerberus/react'
import { ReactiveText, createSignal, useSignal } from '@cerberus/signals'

function createDemoStore() {
  const [renderCount, setRenderCount] = createSignal<number>(0)
  return { renderCount, setRenderCount }
}

export function UseDemo() {
  const store = createDemoStore()
  const [count, setCount, getCount] = useSignal<number>(0)

  const increment = () => setCount(count + 1)

  store.setRenderCount(store.renderCount() + 1)

  return (
    <HStack justify="space-between" w="3/4">
      <HStack gap="md" w="full">
        <Button onClick={increment}>Increment</Button>
        <Text>{count}</Text>
        <ReactiveText data={getCount} />
      </HStack>

      <HStack gap="md" w="full">
        <Text>Render Count:</Text>
        <ReactiveText data={store.renderCount} />
      </HStack>
    </HStack>
  )
}
Copy
'use client'

import { HStack } from '@/styled-system/jsx'
import { Button, Text } from '@cerberus/react'
import { ReactiveText, createSignal, useSignal } from '@cerberus/signals'

function createDemoStore() {
  const [renderCount, setRenderCount] = createSignal<number>(0)
  return { renderCount, setRenderCount }
}

export function UseDemo() {
  const store = createDemoStore()
  const [count, setCount, getCount] = useSignal<number>(0)

  const increment = () => setCount(count + 1)

  store.setRenderCount(store.renderCount() + 1)

  return (
    <HStack justify="space-between" w="3/4">
      <HStack gap="md" w="full">
        <Button onClick={increment}>Increment</Button>
        <Text>{count}</Text>
        <ReactiveText data={getCount} />
      </HStack>

      <HStack gap="md" w="full">
        <Text>Render Count:</Text>
        <ReactiveText data={store.renderCount} />
      </HStack>
    </HStack>
  )
}

0

0

Render Count:

1

0

0

Render Count:

1

0

0

Render Count:

1