decocms / decocms/blocks

React migration: use useSignalValue for module-level signals in render

Open
#423 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
5
Forks
2
Avg merge
20h 12m
Merged PRs (30d)
36

Description

Problem

When porting components from Preact (Deco Fresh) to React (TanStack Start), module-level signals from @decocms/blocks/sdk/signal behave differently:

  • Preact: reading signal.value in render automatically subscribes the component and triggers re-renders on change (Preact signals magic).
  • React: reading signal.value in render does NOT subscribe the component. The value is read once and never updates — the component appears broken (e.g. drawers never open, modals stay closed).

Required pattern in React

// ❌ BROKEN in React — reads once, never re-renders on signal change
const { displayCart } = useUI();
return <Drawer open={displayCart.value} />;

// ✅ CORRECT — useSignalValue uses useSyncExternalStore under the hood
import { useSignalValue } from "~/sdk/signal";
const { displayCart } = useUI();
const displayCartValue = useSignalValue(displayCart);
return <Drawer open={displayCartValue} />;

Writing to signals (signal.value = x) is safe anywhere — only reading in render requires useSignalValue.

Notes

  • useSignal(v) (component-scoped) is backed by useState and is safe to read in render within the same component.
  • Only module-level signals (from signal() in useUI.ts or similar) need useSignalValue when read in render.
  • This pattern affects all UI state components: drawers, modals, toasts, search bars, etc.

Affected files in a typical TanStack Start migration

  • Any component that reads a shared signal from useUI() to control visibility (open/close state).
  • Common symptoms: drawer opens briefly and closes, modal never opens, CSS class never updates reactively.

Related

  • useSignalValue is available from ~/sdk/signal — re-exported from @decocms/blocks/sdk/signal.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating TanStack Start components that read shared signals from useUI(), then read the useSignalValue implementation re-exported from ~/sdk/signal. Update affected render-time reads for drawers, modals, toasts, search bars, and similar UI state, and verify that visibility and CSS state react to signal changes.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.