Skip to content

Umbrella: act #15472

Closed
Closed
@acdlite

Description

@acdlite

Action items

Discussion

  • In Legacy Mode, updates that happen after the first await will not be batched, but they shouldn't fire the warning. We should still wait to flush passive effects, Scheduler, and microtasks until the end.
  • Because passive effects are scheduled with Scheduler, they are flushed by Scheduler.flushAll. That means we don't need to call flushPassiveEffects separately in order to flush them. However, we currently use the return value of flushPassiveEffects to determine if additional passive effects were scheduled. So perhaps we should export a method like hasPendingEffects instead.
  • The recommendation is to await the result of act even if the handler is synchronous, because that ensures that any dangling microtasks are flushed before the test proceeds. However, it's hard to fire a warning if the user neglects to do this, because such a warning needs to happen in an async task, and the test could exit before the async task fires. The warning is also controversial because of the additional boilerplate. But regardless of whether we fire a warning, we should stick to our recommendation to always await act.
  • The API is designed primarily for Batched/Concurrent Mode. That's why we wait until the outermost act exits before flushing anything.
    • The behavior is slightly different in Legacy Mode, but they are the same in the simple case of a single event handler inside a single act. For the remaining cases, our suggestion is to switch to the Batched Mode API.
  • No longer need to count the act "depth" because nested acts are a no-op in Batched Mode.

Idiomatic examples

Single event handler

await act(() => setState());

Using a testing framework

await simulate('click', domElement);

where simulate is imported from a testing framework and looks something like:

async function simulate(eventType, domElement) {
  const event = new Event(eventType);
  await act(() => domElement.dispatchEvent(event));
}

Advanced: Multiple events that occur in sequence

In Batched Mode, these would all be flushed in a single batch, so we group them together with an outer act.

await act(async () => {
  await simulate(domElement, 'mousedown');
  await simulate(domElement, 'mouseup');
});

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions