## Summary
We need to unblock flipping the default for RTR to be concurrent
rendering. Update ReactDevToolsHooksIntegration-test to use
`unstable_isConcurrent` in place.
## How did you test this change?
`yarn test
packages/react-debug-tools/src/__tests__/ReactDevToolsHooksIntegration-test.js`
## Summary
Concurrent rendering has been the default since React 18 release.
ReactTestRenderer requires passing `{unstable_isConcurrent: true}` to
match this behavior, which means by default tests written with RTR use a
different rendering method than the code they test.
Eventually, RTR should only use ConcurrentRoot. As a first step, let's
add a version of the concurrent option that isn't marked unstable. Next
we will follow up with removing the unstable option when it is safe to
merge.
## How did you test this change?
`yarn test
packages/react-test-renderer/src/__tests__/ReactTestRendererAsync-test.js`
This fixes a handful of tests that were accidentally relying on React
synchronously queuing work in the Scheduler after a setState.
Usually this is because they use a lower level SchedulerMock method
instead of either `act` or one of the `waitFor` helpers. In some cases,
the solution is to switch to those APIs. In other cases, if we're
intentionally testing some lower level behavior, we might have to be a
bit more clever.
Co-authored-by: Tianyu Yao <skyyao@fb.com>
This converts some of our test suite to use the `waitFor` test pattern,
instead of the `expect(Scheduler).toFlushAndYield` pattern. Most of
these changes are automated with jscodeshift, with some slight manual
cleanup in certain cases.
See #26285 for full context.
* Facebook -> Meta in copyright
rg --files | xargs sed -i 's#Copyright (c) Facebook, Inc. and its affiliates.#Copyright (c) Meta Platforms, Inc. and affiliates.#g'
* Manual tweaks
* Move isActEnvironment check to function that warns
I'm about to fork the behavior in legacy roots versus concurrent roots
even further, so I'm lifting this up so I only have to fork once.
* Lift `mode` check, too
Similar to previous commit. I only want to check this once. Not for
performance reasons, but so the logic is easier to follow.
* Expand act warning to include non-hook APIs
In a test environment, React warns if an update isn't wrapped with act
— but only if the update originates from a hook API, like useState.
We did it this way for backwards compatibility with tests that were
written before the act API was introduced. Those tests didn't require
act, anyway, because in a legacy root, all tasks are synchronous except
for `useEffect`.
However, in a concurrent root, nearly every task is asynchronous. Even
tasks that are synchronous may spawn additional asynchronous work. So
all updates need to be wrapped with act, regardless of whether they
originate from a hook, a class, a root, or any other type of component.
This commit expands the act warning to include any API that triggers
an update.
It does not currently account for renders that are caused by a Suspense
promise resolving; those are modelled slightly differently from updates.
I'll fix that in the next step.
I also removed the check for whether an update is batched. It shouldn't
matter, because even a batched update can spawn asynchronous work, which
needs to be flushed by act.
This change only affects concurrent roots. The behavior in legacy roots
is the same.
* Expand act warning to include Suspense resolutions
For the same reason we warn when an update is not wrapped with act,
we should warn if a Suspense promise resolution is not wrapped with act.
Both "pings" and "retries".
Legacy root behavior is unchanged.
* Fix native event batching in concurrent mode
* Wrap DevTools test updates with act
These tests expect the `scheduleUpdate` DevTools hook to trigger a
synchronous re-render with legacy semantics, but flushing in a microtask
is fine. Wrapping the updates with `act` fixes it.
* Testing nits
* Nit: Check executionContext === NoContext first
In the common case it will be false and the binary expression will
short circuit.
Co-authored-by: Andrew Clark <git@andrewclark.io>
* update all facebook.github.io links
* facebookincubator links : update some outdated links and fix two other broken links where they are actually the latest updated ones
* Bugfix: Suspended update must finish to unhide
When we commit a fallback, we cannot unhide the content without including
the level that originally suspended. That's because the work at level
outside the boundary (i.e. everything that wasn't hidden during that
render) already committed.
* Test unblocking with a high-pri update
* Track the earliest event time in this render
Rebase
* Track the time of the fallback being shown as an event time
When we switch back from fallback to content, we made progress and we track
the time from when we showed the fallback in the first place as the
last time we made progress.
* Don't retry if synchronous
* Only suspend when we switch to fallback mode
This ensures that we don't resuspend unnecessarily if we're just retrying
the same exact boundary again. We can still unnecessarily suspend
for nested boundaries.
* Rename timedOutAt to fallbackExpirationTime
* Account for suspense in devtools suspense test
* Allow DevTools to toggle Suspense state
* Change API to overrideSuspense
This lets detect support for overriding Suspense from DevTools.
* Add ConcurrentMode test
* Newlines
* Remove unnecessary change
* Naming changes
* ReactDebugHooks identifies State and Reducer hooks as editable
* Inject overrideHookState() method to DevTools to support editing in DEV builds
* Added an integration test for React DevTools, react-debug-tools, and overrideHookState