Commit Graph
15135 Commits
Author SHA1 Message Date
kwzrandGitHub c8b778b7f4 Fix typo: supportsMicrotask -> supportsMicrotasks (#25142) 2022-08-25 16:56:24 +01:00
Sebastian MarkbågeandGitHub d0f396651b Allow functions to be used as module references (#25137) 2022-08-25 07:47:38 -04:00
Sebastian MarkbågeandGitHub 38c5d8a035 Test the node-register hooks in unit tests (#25132) 2022-08-24 19:05:39 -04:00
Tianyu YaoandGitHub 3f70e68cea Return closestInstance in getInspectorDataForViewAtPoint (#25118) 2022-08-24 11:26:08 -07:00
Tianyu YaoandGitHub 181525338e [DevTools] Highlight RN elements on hover (#25106)
* [DevTools] Highlight RN elements on hover

* Remove unused TODO
2022-08-24 11:25:22 -07:00
3d443cad74 Update fixtures/flight to webpack 5 (#25115)
* Add new flight fixture

* Move flight dir files

* Enable writeToDisk and distDir

* Move flight2 -> flight

* flight2 -> flight

* Remove unused files

* Remove unused files

* Run prettier

* Ignore eslint cache

Co-authored-by: Sebastian Markbage <sebastian@calyptus.eu>
2022-08-23 21:18:05 -04:00
Samuel SuslaandGitHub 5d1ce65139 Align StrictMode behaviour with production (#25049)
* Skip double invoking effects in Offscreen

* Run yarn replace-fork

* Use executionContext to disable profiler timer

* Restructure recursion into two functions

* Fix ReactStrictMode test

* Use gate pragma in ReacetOffscreenStrictMode test

* Set and reset current debug fiber in dev

* Skip over paths that don't include any insertions

* Extract common logic to check for profiling to a helper function

* Remove hasPassiveEffects flag from StrictMode

* Fix flow issues

* Revert "Skip over paths that don't include any insertions"
2022-08-23 18:19:07 +01:00
9e67e7a315 Scaffolding for useMemoCache hook (#25123)
* Scaffolding for useMemoCache hook
* cleanup leftovers from copy/paste of use() diff

Co-authored-by: Andrew Clark <git@andrewclark.io>
2022-08-23 09:36:02 +01:00
taigaandGitHub e25648b0a8 devtools: Fix typo from directores to directories (#25124) 2022-08-22 18:40:26 +02:00
EvrenandGitHub 1b69a8bb73 fixture: Fix typo from perfomrance to performance (#25100) 2022-08-21 21:16:01 +02:00
Tianyu YaoandGitHub 26ba5fb2e0 [DevTools] Add events necessary for click to inspect on RN (#25111)
* Add inspectingNative events for RN

* Enable inspection toggle UI for RN

* Add a stopInspectingNative method for agent
2022-08-19 16:18:14 -07:00
Jiachi LiuandGitHub 19e9a4c68e Add missing createServerContext for experimental shared subset (#25114) 2022-08-18 09:33:36 -04:00
Josh StoryandGitHub 1e5245df89 support subresource integrity for bootstrapScripts and bootstrapModules (#25104) 2022-08-17 08:31:05 +01:00
Josh StoryandGitHub 6ef466c681 make preamble and postamble types explicit and fix typo (#25102) 2022-08-16 12:17:49 +01:00
Josh StoryandGitHub 796d31809b Implement basic stylesheet Resources for react-dom (#25060)
Implement basic support for "Resources". In the context of this commit, the only thing that is currently a Resource are

<link rel="stylesheet" precedence="some-value" ...>

Resources can be rendered anywhere in the react tree, even outside of normal parenting rules, for instance you can render a resource before you have rendered the <html><head> tags for your application. In the stream we reorder this so the browser always receives valid HTML and resources are emitted either in place (normal circumstances) or at the top of the <head> (when you render them above or before the <head> in your react tree)

On the client, resources opt into an entirely different hydration path. Instead of matching the location within the Document these resources are queried for in the entire document. It is an error to have more than one resource with the same href attribute.

The use of precedence here as an opt-in signal for resourcifying the link is in preparation for a more complete Resource implementation which will dedupe resource references (multiple will be valid), hoist to the appropriate container (body, head, or elsewhere), order (according to precedence) and Suspend boundaries that depend on them. More details will come in the coming weeks on this plan.

This feature is gated by an experimental flag and will only be made available in experimental builds until some future time.
2022-08-12 13:27:53 -07:00
Luna RuanandGitHub 32baab38f8 [Transition Tracing] Add Tag Field to Marker Instance (#25085)
We were previously using `markerInstance.name` to figure out whether the marker instance was on the tracing marker or the root, but this is unsustainable. This adds a tag field so we can explicitly check this.
2022-08-11 23:04:45 -04:00
Andrew ClarkandGitHub 8ef3a7c08c Resume immediately pinged fiber without unwinding (#25074)
* Yield to main thread if continuation is returned

Instead of using an imperative method `requestYield` to ask Scheduler to
yield to the main thread, we can assume that any time a Scheduler task
returns a continuation callback, it's because it wants to yield to the
main thread. We can assume the task already checked some condition that
caused it to return a continuation, so we don't need to do any
additional checks — we can immediately yield and schedule a new task
for the continuation.

The replaces the `requestYield` API that I added in ca990e9.

* Move unwind after error into main work loop

I need to be able to yield to the main thread in between when an error
is thrown and when the stack is unwound. (This is the motivation behind
the refactor, but it isn't implemented in this commit.) Currently the
unwind is inlined directly into `handleError`.

Instead, I've moved the unwind logic into the main work loop. At the
very beginning of the function, we check to see if the work-in-progress
is in a "suspended" state — that is, whether it needs to be unwound. If
it is, we will enter the unwind phase instead of the begin phase.

We only need to perform this check when we first enter the work loop:
at the beginning of a Scheduler chunk, or after something throws. We
don't need to perform it after every unit of work.

* Yield to main thread whenever a fiber suspends

When a fiber suspends, we should yield to the main thread in case the
data is already cached, to unblock a potential ping event.

By itself, this commit isn't useful because we don't do anything special
in the case where to do receive an immediate ping event. I've split this
out only to demonstrate that it doesn't break any existing behavior.

See the next commit for full context and motivation.

* Resume immediately pinged fiber without unwinding

If a fiber suspends, and is pinged immediately in a microtask (or a
regular task that fires before React resumes rendering), try rendering
the same fiber again without unwinding the stack. This can be super
helpful when working with promises and async-await, because even if the
outermost promise hasn't been cached before, the underlying data may
have been preloaded. In many cases, we can continue rendering
immediately without having to show a fallback.

This optimization should work during any concurrent (time-sliced)
render. It doesn't work during discrete updates because those are
semantically required to finish synchronously — those get the current
behavior.
2022-08-11 22:01:56 -04:00
Robert BalickiandGitHub 4e60dbd905 [easy] Clarify folders in react devtools readme #25077
Clarify the folder from which we run various commands in the react-devtools readme
2022-08-11 19:47:02 -04:00
Samuel SuslaandGitHub 7bcc687720 Remove argument committedLanes from reappearLayoutEffects and recursivelyTraverseReappearLayoutEffects (#25080) 2022-08-11 14:24:56 +01:00
ZA SyedandGitHub 7a227276e6 revert last grammatical edit (#25067)
on line 29, #24798 edited (others') to (other's); however, the subject here is plural (e.g. "others in the community"), thus (others') is grammatically correct
2022-08-10 20:14:31 +01:00
Krishnamohan YerrabilliandGitHub 17e2a15bea Added a comma to understand better the Readme file for the contributor and the viewer. (#24798)
* Small change for Readme file

Added a comma, for better understanding for the contributor and the viewer.

* Update CODE_OF_CONDUCT.md

* Updated, requested changes are done!
2022-08-08 07:31:34 -04:00
Andrew ClarkandGitHub ca990e9a75 Add API to force Scheduler to yield for macrotask (#25044)
We need a way to yield control of the main thread and schedule a
continuation in a separate macrotask. (This is related to some Suspense
optimizations we have planned.)

Our solution needs account for how Scheduler is implemented. Scheduler
tasks are not 1:1 with real browser macrotasks — many Scheduler "tasks"
can be executed within a single browser task. If a Scheduler task yields
control and posts a continuation, but there's still time left in the
frame, Scheduler will execute the continuation immediately
(synchronously) without yielding control back to the main thread. That's
not what we want — we want to schedule a new macrotask regardless of
where we are in the browser's render cycle.

There are several ways we could approach this. What I ended up doing was
adding a new Scheduler method `unstable_requestYield`. (It's similar to
the existing `unstable_requestPaint` that we use to yield at the end of
the frame.)

It works by setting the internal start time of the current work loop to
a large negative number, so that when the `shouldYield` call computes
how much time has elapsed, it's guaranteed to exceed the deadline. The
advantage of doing it this way is that there are no additional checks in
the normal hot path of the work loop.

The existing layering between Scheduler and React DOM is not ideal. None
of the APIs are public, so despite the fact that Scheduler is a separate
package, I consider that a private implementation detail, and think of
them as part of the same unit.

So for now, though, I think it makes sense to implement this macrotask
logic directly inside of Scheduler instead of layering it on top.

The rough eventual plan for Scheduler is turn it into a `postTask`
prollyfill. Because `postTask` does not yet have an equivalent for
`shouldYield`, we would split that out into its own layer, perhaps
directly inside the reconciler. In that world, the macrotask logic I've
added in this commit would likely live in that same layer. When the
native `postTask` is available, we may not even need any additional
logic because it uses actual browser tasks.
2022-08-04 21:20:15 -04:00
Andrew ClarkandGitHub b4204ede66 Clean up unused Deletion flag (#24992)
This was replaced by the ChildDeletion flag when we refactored the 
commit phase.
2022-08-03 17:03:53 -04:00
Luna RuanandGitHub e193be87e6 [Transition Tracing] Add Offscreen Test (#25035)
Add a test to make sure offscreen trees don't stop transitions from completing.
2022-08-03 13:24:41 -04:00
Sebastian MarkbågeandGitHub 9fcaf88d58 Remove rootContainerInstance from unnecessary places (#25024)
We only really use this for the create APIs since the DOM requires it.

We could probably use the Host Context for this instead since they're
updated at the same time and the namespace is related to this concept.
2022-08-01 23:30:04 -04:00
Konpaku YoumuandGitHub 3f3b46c845 docs(react-devtools-inline): react-dom@experimental instead of react-dom@experimenal (#25001) 2022-07-30 10:57:13 +02:00
Andrew ClarkandGitHub 80f3d88190 Mount/unmount passive effects when Offscreen visibility changes (#24977)
* Remove unnecessary try-catch from passive deletion

The individual unmount calls are already wrapped in a catch block, so
this outer one serves no purpose.

* Extract passive unmount effects to separate functions
    
I'm about to add a "disconnect passive effects" function that will share
much of the same code as commitPassiveUnmountOnFiber. To minimize the
duplicated code, I've extracted the shared parts into separate
functions, similar to what I did for commitLayoutEffectOnFiber and
reappearLayoutEffects.

This may not save much on code size because Closure will likely inline
some of it, anyway, but it makes it harder for the two paths to
accidentally diverge.

* Mount/unmount passive effects on hide/show

This changes the behavior of Offscreen so that passive effects are
unmounted when the tree is hidden, and re-mounted when the tree is
revealed again. This is already how layout effects worked.

In the future we will likely add an option or heuristic to only unmount
the effects of a hidden tree after a delay. That way if the tree quickly
switches back to visible, we can skip toggling the effects entirely.

This change does not apply to suspended trees, which happen to use
the Offscreen fiber type as an implementation detail. Passive effects
remain mounted while the tree is suspended, for the reason described
above — it's likely that the suspended tree will resolve and switch
back to visible within a short time span.

At a high level, what this capability enables is a feature we refer to
as "resuable state". The real value proposition here isn't so much the
behavior of effects — it's that you can switch back to a previously
rendered tree without losing the state of the UI.

* Add more coverage for nested Offscreen cases
2022-07-29 19:34:28 -04:00
Andrew ClarkandGitHub 4ea064eb09 Don't fire passive effects during initial mount of a hidden Offscreen tree (#24967)
* Change OffscreenInstance isHidden to bitmask

The isHidden field of OffscreenInstance is a boolean that represents
whether the tree is currently hidden. To implement resuable effects, we
need to also track whether the passive effects are currently connected.
So I've changed this field to a bitmask.

No other behavior has changed in this commit. I'll update the effects
behavior in the following steps.

* Extract passive mount effects to separate functions

I'm about to add a "reappear passive effects" function that will share
much of the same code as commitPassiveMountEffectOnFiber. To minimize
the duplicated code, I've extracted the shared parts into separate
functions, similar to what I did for commitLayoutEffectOnFiber and
reappearLayoutEffects.

This may not save much on code size because Closure will likely inline
some of it, anyway, but it makes it harder for the two paths to
accidentally diverge.

* Don't mount passive effects in a new hidden tree

This changes the behavior of Offscreen so that passive effects do not
fire when prerendering a brand new tree. Previously, Offscreen did not
affect passive effects at all — only layout effects, which mount or
unmount whenever the visibility of the tree changes.

When hiding an already visible tree, the behavior of passive effects is
unchanged, for now; unlike layout effects, the passive effects will not
get unmounted. Pre-rendered updates to a hidden tree in this state will
also fire normally. This is only temporary, though — the plan is for
passive effects to act more like layout effects, and unmount them when
the tree is hidden. Perhaps after a delay so that if the visibility
toggles quickly back and forth, the effects don't need to remount. I'll
implement this separately.

* "Atomic" passive commit effects must always fire

There are a few cases where commit phase logic always needs to fire even
inside a hidden tree. In general, we should try to design algorithms
that don't depend on a commit effect running during prerendering, but
there's at least one case where I think it makes sense.

The experimental Cache component uses reference counting to keep track
of the lifetime of a cache instance. This allows us to expose an
AbortSignal object that data frameworks can use to cancel aborted
requests. These cache objects are considered alive even inside a
prerendered tree.

To implement this I added an "atomic" passive effect traversal that runs
even when a tree is hidden. (As a follow up, we should add a special
subtree flag so that we can skip over nodes that don't have them. There
are a number of similar subtree flag optimizations that we have planned,
so I'll leave them for a later refactor.)

The only other feature that currently depends on this behavior is
Transition Tracing. I did not add a test for this because Transition
Tracing is still in development and doesn't yet work with Offscreen.
2022-07-29 19:22:57 -04:00
Andrew ClarkandGitHub 2c7dea7365 Implement Offscreen in Fizz (#24988)
During server rendering, a visible Offscreen subtree acts exactly like a
fragment: a pure indirection.

A hidden Offscreen subtree is not server rendered at all. It's ignored
during hydration, too. Prerendering happens only on the client. We
considered prerendering hidden trees on the server, too, but our
conclusion is that it's a waste of bytes and server computation. We
can't think of any compelling cases where it's the right trade off. (If
we ever change our mind, though, the way we'll likely model it is to
treat it as if it's a Suspense boundary with an empty fallback.)
2022-07-26 00:35:51 -04:00
Mengdi ChenandGitHub 5f34b051df [Devtools] add logs for profiler tab switch & settings change (#24966)
* [devtools] add logs for profiler tab switch & settings change

* prettier

* remove unnecessary console.log

* better naming: logEvent -> loggerEvent

* use same object for event and metadata
2022-07-25 11:53:38 -04:00
Sebastian SilbermannandGitHub b66936ece7 devtools: Remove ForwardRef/Memo from display name if displayName is set (#21952)
* feat(devtools): Remove ForwardRef/Memo from display name if `displayName` is set

* Avoid potentially wasting work by inlining `functionName`
2022-07-25 09:02:12 +02:00
davidrenneandGitHub 49f8254d6d Bug fix for <App /> vs. <Counter /> (#24972) 2022-07-22 11:24:49 -04:00
Sebastian SilbermannandGitHub 6b28bc9c5a test: Throw custom error instead of relying on runtime error (#24946) 2022-07-21 15:46:57 -04:00
Sebastian SilbermannandGitHub 9bd0dd4c18 test(react-debug-tools): Improve coverage of currentDispatcher.current setter (#24945) 2022-07-21 15:46:43 -04:00
Sebastian SilbermannandGitHub 59bc52a16c Add 4.5.0 release to eslint rules CHANGELOG (#24853)
Eye-balled from https://app.renovatebot.com/package-diff?name=eslint-plugin-react-hooks&from=4.4.0&to=4.5.0#d2h-042857 which changes were included.
2022-07-21 15:46:10 -04:00
Mengdi ChenandGitHub 3ddbedd052 [devtools] log more events + metadata (#24951)
* [devtools] log more events + metadata

* better typing

* consistent string type
2022-07-19 15:22:09 -04:00
Andrew Clark cfb6cfa250 Reused components commit with timing as new ones
When an Offscreen tree goes from hidden -> visible, the tree may include
both reused components that were unmounted when the tree was hidden, and
also brand new components that didn't exist in the hidden tree.

Currently when this happens, we commit all the reused components'
effects first, before committing the new ones, using two separate
traversals of the tree.

Instead, we should fire all the effects with the same timing as if it
were a completely new tree. See the test I wrote for an example.

This is also more efficient because we only need to traverse the
tree once.
2022-07-19 14:11:33 -04:00
Andrew Clark 679eea3282 Extract layout effects to separate functions
There's a lot of duplicated code between commitLayoutEffectOnFiber and the
"reappear layout effects" path that happens when an Offscreen tree goes from
hidden back to visible. I'm going to refactor these to share more of the same
code. As a first step, this extracts the shared parts into separate functions.

This may not save much on code size because Closure will likely inline some of
it, anyway, but it makes it harder for the two paths to accidentally diverge.
2022-07-19 14:11:32 -04:00
Andrew Clark 41287d4475 Use recursion to traverse during "reappear layout" phase
This converts the "reappear layout" phase to iterate over its effects
recursively instead of iteratively. This makes it easier to track
contextual information, like whether a fiber is inside a hidden tree.

We already made this change for several other phases, like mutation and
layout mount. See 481dece for more context.
2022-07-19 14:11:32 -04:00
Andrew Clark 697702bf34 Use recursion to traverse during "disappear layout" phase
This converts the "disappear layout" phase to iterate over its effects
recursively instead of iteratively. This makes it easier to track
contextual information, like whether a fiber is inside a hidden tree.

We already made this change for several other phases, like mutation and
layout mount. See 481dece for more context.
2022-07-19 14:11:32 -04:00
Mengdi ChenandGitHub 992911981b [DevTools] add simple usage events for internal logging (#24888)
* [DevTools] add simple events for internal logging

* fix lint

* fix lint

* better event name

* fix flow

* better way to fix flow

* combine 'select-element'

* use same event name for selecting element by inspecting
2022-07-18 15:52:53 -04:00
Luna RuanandGitHub 6daf600609 add transistion callbacks to hydrateRoot (#24937)
This PR adds transition callbacks to hydrateRoot.
2022-07-18 10:22:47 -07:00
Andrew ClarkandGitHub 02206099af Use recursion to traverse during passive unmount phase (#24918)
This converts the layout phase to iterate over its effects recursively
instead of iteratively. This makes it easier to track contextual
information, like whether a fiber is inside a hidden tree.

We already made this change for several other phases, like mutation and
layout mount. See 481dece for more context.
2022-07-14 11:08:08 -04:00
Mengdi ChenandGitHub d54880d424 React DevTools 4.24.7 -> 4.25.0 (#24919) 2022-07-13 15:57:50 -04:00
Luna RuanandGitHub f629495199 [Transition Tracing] Rename transitionCallbacks to unstable_transitionCallbacks (#24920)
Renaming transitionCallbacks to unstable_transitionCallbacks as per convention
2022-07-13 15:27:12 -04:00
Mengdi ChenandGitHub 4bc83e6821 [DevTools] enable enableProfilerComponentTree flag for all builds (#24921) 2022-07-13 15:21:32 -04:00
Andrew Clark 7a4336c404 Use recursion to traverse during passive mount phase
This converts the layout phase to iterate over its effects
recursively instead of iteratively. This makes it easier to track 
contextual information, like whether a fiber is inside a hidden tree.

We already made this change for the mutation phase. See 481dece for
more context.
2022-07-12 16:06:53 -04:00
Andrew Clark bb1357b381 Wrap try-catch directly around each user function
(This is the same as f9e6aef, but for the passive mount phase rather than the
mutation phase.)

This moves the try-catch from around each fiber's passive mount phase to
direclty around each user function (effect function, callback, etc).

We already do this when unmounting because if one unmount function
errors, we still need to call all the others so they can clean up
their resources.

Previously we didn't bother to do this for anything but unmount,
because if a mount effect throws, we're going to delete that whole
tree anyway.

But now that we're switching from an iterative loop to a recursive one,
we don't want every call frame on the stack to have a try-catch, since
the error handling requires additional memory.

Wrapping every user function is a bit tedious, but it's better
for performance. Many of them already had try blocks around
them already.
2022-07-12 16:06:53 -04:00
Andrew Clark de3c069843 Move flag check into each switch case
The fiber tag is more specific than the effect flag, so we should always
refine the type of work first, to minimize redundant checks.
2022-07-12 16:06:53 -04:00
Luna RuanandGitHub f5916d15b6 [Transition Tracing][Code Cleanup] Delete Marker Name Change Tests (#24908)
We decided that changing the Tracing Marker name wasn't allowed and we would error, so this PR deletes all the tests that tested name change behavior
2022-07-12 12:59:58 -07:00