question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

State updates outside of `act` interfere with subsequent state updates during `act`

See original GitHub issue

A state update to a component scheduled outside of an act() callback can prevent a state update scheduled inside of an act() callback from executing synchronously as it should:

Steps to reproduce:

import { createElement, render } from "preact";
import { useState, useEffect } from "preact/hooks";
import { act } from "preact/test-utils";

function App({ foo }) {
  const [fooState, setFooState] = useState(null);
  useEffect(() => {
    setFooState(foo);
  }, [foo, setFooState]);

  return <div>{fooState}</div>;
}

const container = document.querySelector("#app");

render(<App foo={1} />, container);
act(() => {
  render(<App foo={2} />, container);
});
console.log("initial render output", container.innerHTML);

Runnable demo: https://codesandbox.io/s/preact-10-state-update-after-unmount-y1fj0

nb. With this sandbox I see different outputs in the DOM when viewing the sandbox output in an iframe vs a new window. In the iframe the DOM output matches the console log. In a new window, the DOM updates after the console log to show “2”.

Expected output:

"initial render output <div>2</div>"

Actual output:

"initial render output <div>1</div>"

Notes:

When setState is called or a state update hook runs, the enqueueRender function is called. This function uses the options.debounceRendering hook which is overridden in the context of an act call. However, options.debounceRendering is only called if the deferred rendering queue is empty. In the above example, when the component is updated inside the act call, the queue is non-empty so rendering is deferred.

The above example was extracted from a test where a state update was being triggered in a timeout, outside of an act call, to work around an issue with CSS transitions in certain browsers. This surprisingly interfered with later tests due to the global deferred render queue.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:6 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
robertknightcommented, Jul 23, 2019

As far as I know it is because your first render should also be incorporated into act since this triggers hooks without an updated options.debounceRendering.

In the context that I extracted this test case from, the state update is triggered asynchronously inside a useEffect handler using setTimeout, so it is difficult to wrap in act. I’m sure I could figure out something for that specific test. The bigger issue though is that this issue creates a footgun which is very confusing to debug because something that one test does can affect what happens in later, unrelated tests, due to the global queues used for deferred rendering.

0reactions
robertknightcommented, Aug 10, 2019

On reflection I realized that there was a more general issue here to do with the way the scheduling hooks (options.{debounceRendering, requestAnimationFrame}) are handled that could break other code that temporarily changes these hooks for any reason.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Jest + react-testing-library: Warning update was not wrapped ...
The act warning is simply telling you that there is something happening in your functional component which you're not testing.
Read more >
Status of State Medicaid Expansion Decisions: Interactive Map
This page displays an interactive map of the current status of state decisions on the Affordable Care Act's Medicaid expansion.
Read more >
FOIA Update: The Freedom of Information Act, 5 U.S.C. sect ...
FOIA Update Vol. XVII, No. 4 1996. The Freedom of Information Act 5 U.S.C. § 552, As Amended By Public Law No. 104-231,...
Read more >
THE CONNECTICUT FAMILY & MEDICAL LEAVE ACT and ...
The CT Family and Medical Leave Act provides eligible employees with ... At this time, there are no federal or state laws that...
Read more >
After Roe Fell: Abortion Laws by State
Click through this tool to learn about all the bans and restrictions currently on the books in each state. This tool is updated...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found