Scope rx.foreach loop vars per item

MA
5h ago
+1427-84

All Submissions:

  • Have you followed the guidelines stated in CONTRIBUTING.md file?
  • Have you checked to ensure there aren't any other open Pull Requests for the desired changed?

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • This change requires a documentation update

Description

Follow-up to #6936, which this PR is stacked on. It carries the rx.foreach loop-var scoping that was split out of that PR.

What changes for users

  • The item and index of an rx.foreach are available anywhere in the item's subtree, including event handlers the compiler hoists into useCallback and descendants it compiles into their own memo modules. Fixes #3210.
  • Each loop item renders through a component of its own, so an unnamed rx.client_state var declared in the item function is per item, and it can be seeded from the item or index.
  • An explicit key= on the item is used to key the list; otherwise it is keyed by position as before.
  • Inside an explicit @rx.memo body a loop is not split up, so per-item client state there still uses an @rx.memo item function. The foreach docs say so.

Implementation

  • IterTag builds loop vars with scoped_loop_var, which reads the value from an enclosing ScopedValues provider through useScopedValue; the map callback's parameter shadows the hook inside the loop body itself.
  • Foreach renders each item inside ScopedValues, which also opens a client state scope, and no longer seals its subtree from auto-memoization.
  • MemoizeStatefulPlugin wraps each loop item in a snapshot memo component after a sealed sub-walk over the item, and a forced snapshot body is hashed by its whole subtree.

Changes To Core Features:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your core changes, as applicable?
  • Have you successfully ran tests with your changes locally? (unit, JS, Playwright; ruff and pyright clean)

Generated by Claude Code