Skip to content

Conversation

@Madoshakalaka
Copy link
Member

@Madoshakalaka Madoshakalaka commented Dec 19, 2025

Description

The UseReducerHandle was caching a snapshot of state at render time.
When set() was called, the underlying RefCell was updated, but callback
closures still held handles pointing to old snapshots. This caused
stale state reads when multiple events fired before a rerender.

The fix changes UseReducerHandle to:

  1. Store both a reference to the shared RefCell AND a snapshot
  2. Use try_borrow() to read from RefCell when possible
  3. Fall back to snapshot when RefCell is borrowed (during dispatch)

This ensures callbacks see the latest state in normal operation while
avoiding panics when state is read during reducer execution (e.g., SSR).

Changes:

  • UseReducerHandle now stores both current_state RefCell ref and snapshot
  • Deref uses try_borrow with fallback to snapshot
  • Updated Clone, Debug, PartialEq implementations
  • Added regression test for the stale state scenario

Fixes #3796

Checklist

  • I have reviewed my own code
  • I have added tests

@github-actions
Copy link

github-actions bot commented Dec 19, 2025

Benchmark - core

Yew Master

vnode           fastest       │ slowest       │ median        │ mean          │ samples │ iters
╰─ vnode_clone  2.401 ns      │ 3.666 ns      │ 2.406 ns      │ 2.528 ns      │ 100     │ 1000000000

Pull Request

vnode           fastest       │ slowest       │ median        │ mean          │ samples │ iters
╰─ vnode_clone  2.435 ns      │ 3.695 ns      │ 2.438 ns      │ 2.49 ns       │ 100     │ 1000000000

@github-actions
Copy link

github-actions bot commented Dec 19, 2025

Visit the preview URL for this PR (updated for commit 6f0b966):

https://yew-rs--pr3963-fix-stale-state-issu-iujte35q.web.app

(expires Fri, 26 Dec 2025 04:49:27 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

@github-actions
Copy link

github-actions bot commented Dec 19, 2025

Size Comparison

Details
examples master (KB) pull request (KB) diff (KB) diff (%)
async_clock 98.371 98.371 0 0.000%
boids 168.064 168.064 0 0.000%
communication_child_to_parent 91.499 91.499 0 0.000%
communication_grandchild_with_grandparent 102.606 102.606 0 0.000%
communication_grandparent_to_grandchild 98.987 98.987 0 0.000%
communication_parent_to_child 88.859 88.859 0 0.000%
contexts 104.146 104.207 +0.062 +0.059%
counter 85.530 85.530 0 0.000%
counter_functional 85.895 86.039 +0.145 +0.168%
dyn_create_destroy_apps 88.698 88.698 0 0.000%
file_upload 98.330 98.330 0 0.000%
function_delayed_input 91.414 91.603 +0.188 +0.206%
function_memory_game 170.055 170.503 +0.448 +0.264%
function_router 329.168 329.847 +0.679 +0.206%
function_todomvc 161.833 162.228 +0.395 +0.244%
futures 236.338 236.338 0 0.000%
game_of_life 103.926 103.926 0 0.000%
immutable 246.370 246.486 +0.116 +0.047%
inner_html 80.014 80.014 0 0.000%
js_callback 107.929 108.117 +0.188 +0.175%
keyed_list 179.217 179.217 0 0.000%
mount_point 83.230 83.230 0 0.000%
nested_list 112.803 112.803 0 0.000%
node_refs 90.874 90.874 0 0.000%
password_strength 1742.563 1742.563 0 0.000%
portals 92.370 92.370 0 0.000%
router 302.281 302.399 +0.118 +0.039%
suspense 111.874 112.029 +0.155 +0.139%
timer 88.158 88.158 0 0.000%
timer_functional 96.204 96.447 +0.243 +0.253%
todomvc 141.639 141.639 0 0.000%
two_apps 85.394 85.394 0 0.000%
web_worker_fib 133.512 133.862 +0.351 +0.263%
web_worker_prime 185.091 185.527 +0.437 +0.236%
webgl 82.650 82.650 0 0.000%

✅ None of the examples has changed their size significantly.

@Madoshakalaka Madoshakalaka force-pushed the fix/stale-state-issue-3796 branch from e895a14 to b53017d Compare December 19, 2025 03:02
@github-actions
Copy link

github-actions bot commented Dec 19, 2025

Benchmark - SSR

Yew Master

Details
Benchmark Round Min (ms) Max (ms) Mean (ms) Standard Deviation
Baseline 10 290.951 292.175 291.222 0.346
Hello World 10 521.577 526.683 523.342 1.721
Function Router 10 1724.673 1776.752 1742.831 15.514
Concurrent Task 10 1005.368 1007.183 1006.574 0.585
Many Providers 10 1108.893 1207.702 1139.584 28.007

Pull Request

Details
Benchmark Round Min (ms) Max (ms) Mean (ms) Standard Deviation
Baseline 10 310.602 311.460 310.958 0.251
Hello World 10 514.773 566.560 529.352 14.194
Function Router 10 1737.771 1782.760 1757.753 14.452
Concurrent Task 10 1006.219 1007.404 1006.843 0.391
Many Providers 10 1097.124 1143.373 1111.597 14.878

@Madoshakalaka Madoshakalaka marked this pull request as ready for review December 19, 2025 04:33
github-actions[bot]
github-actions bot previously approved these changes Dec 19, 2025
@Madoshakalaka Madoshakalaka changed the title Fix stale state in callbacks when multiple events fire rapidly (#3796) Fix stale state in callbacks when multiple events fire rapidly Dec 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

State management and event handling interact badly leading to stale state

2 participants