Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Bug: Attachment callback is running before the pending UI update. They should run after any pending UI updates, just like how standalone $effects behave. #16395

Open
@sreekar339339

Description

@sreekar339339

Describe the bug: Attachment callback is running before the pending UI updates which is an unexpected behaviour / bug. They should run after any pending UI updates, just like how standalone $effects behave.

https://svelte.dev/playground/195d38aeb8904649befaac64f0a856c4?version=5.36.2

How to reproduce?

  1. Play the TicTacToe game in the provided playground link WITH KEYBOARD ONLY until the game is finished (either winning or draw). Manage focus and navigate the focus on the cells using the Tab key and press the Enter key to make a move.
  2. After the game is over, navigate to the "Reset History" button by shifting the focus using the Tab key.
  3. Press Enter on the "Reset History" button.

The expected outcome is the focus should automatically shift from the "Reset History" button back to the first cell in the game. But that does not happen. The reason is the{@attach} attachment callback responsible for focus management is NOT behaving as expected.

  1. ThecaptureFocus method on App class handles shifting of focus to the desired element referenced bythis.nextEleToFocus state variable.
  2. ThiscaptureFocus method runs automatically afterresetHistory method (the event handler of "Reset History" button) is executed, becausecaptureFocus is run inside an implicit effect, since it is an{@attach} attachment on.container element. The state mutations caused byresetHistory resets all the state used in the component, which results in all cells being back to active, which were previously in disabled state.
  3. The problem iscaptureFocus method is executed before all the queued pending UI updates (caused by state mutations of theresetHistory method) are committed to the DOM. The DOM whencaptureFocus is invoked is in a stale/pre-mature state, where all the game cells are indisabled state i.e the history reset is not yet committed to the DOM, hence setting focus on the first cell does not work as expected.

When the samecaptureFocus function is used inside a standalone$effect instead of an attachment, this bug is not seen. The standalone $effect waits before all the pending UI updates caused by state mutations fromresetHistory method are committed to the DOM, before running the effect callback. The focus is correctly shifted to the first cell after pressing the Enter key on "Reset History" button.

As a quickfix, Im using thetick() function to manually wait for pending UI updates inside thecaptureFocus method (when used as an attachment) before firing the focus() method on the desired element. This quickfix is not needed for the standalone effect approach.

classApp{                 ...resetHistory=()=>{this.history.reset()this.setFocusTo(this.selector.cell(0))}...captureFocus=async(container)=>{if(!this.nextEleToFocus)return// await tick() // tick should not be needed but used as a quickfix.container.querySelector(this.nextEleToFocus.selector).focus()}...}constapp=newApp()// let container <- bind this to the '.container' element, uncomment these lines, and remove the {@attach} code on '.container' element to test the $standalone effect behaviour.// $effect(() => app.captureFocus(container));...

Reproduction

https://svelte.dev/playground/195d38aeb8904649befaac64f0a856c4?version=5.36.2

System Info

Playground env version=5.36.2

Severity

annoyance

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp