/// /** * TEST PATTERN: onClick Handler Inside derive() - VERIFIED BROKEN * * CLAIM: onClick handlers inside derive() cause ReadOnlyAddressError * SOURCE: folk_wisdom/onclick-handlers-conditional-rendering.md * STATUS: ✅ VERIFIED (2024-12-11) * * VERIFIED BEHAVIOR: * - Test 1 (top-level): WORKS - count increments * - Test 2 (derive + closure): FAILS - ReadOnlyAddressError * - Test 3 (derive + param): FAILS - ReadOnlyAddressError * * CONCLUSION: Cell references passed to handlers when binding occurs inside derive() * become read-only proxies. Any subsequent .set() call on those cells fails with * ReadOnlyAddressError. The issue is not the handler definition or the button itself, * but the cell references captured at the point of handler binding inside derive(). */ import { Cell, Default, derive, handler, NAME, pattern, UI } from "commontools"; interface State { count: Default; } const incrementHandler = handler }>( (_event, { count }) => { count.set(count.get() + 1); }, ); export default pattern(({ count }) => { return { [NAME]: "TEST: onClick in derive() - Comparison", [UI]: (

Testing: Buttons Inside derive()

Current count: {count}

{/* TEST 1: Button at top level - CONTROL (should work) */}

Test 1: Top-level button (CONTROL)

Button outside derive() - expected to WORK

Increment (Top-level)
{/* TEST 2: Button inside derive, using closure variable */}

Test 2: Inside derive(), closure variable

Button inside derive(), handler uses `count` from closure

{derive( { count }, () => ( Increment (derive + closure) ), )}
{/* TEST 3: Button inside derive, using derive parameter */}

Test 3: Inside derive(), derive parameter

Button inside derive(), handler uses `c` from derive params

{derive( { count }, ({ count: c }) => ( Increment (derive + param) ), )}

Instructions:

  1. Open browser DevTools Console (Cmd+Option+J)
  2. Click each button in order
  3. Note which ones increment the count vs show errors
  4. Record results to determine if claim is TRUE or FALSE
), count, }; });