Commit Graph

14486 Commits

Author SHA1 Message Date
Konstantin Popov acf8ada4c0 Fix typo in types.js (react-devtools-shared) (#22299)
Fix typo:

becuase -> because
2021-09-20 15:09:59 -04:00
BIKI DAS c62d5831d3 react-devtools\OVERVIEW.md --> fixed typos (#22372) 2021-09-20 15:09:37 -04:00
Brian Vaughn 7e8fb98e14 Enabled enableProfilerChangedHookIndices feature flag for all builds (#22365) 2021-09-20 13:10:50 -04:00
Sebastian Silbermann 3ee7a004e5 devtools: Display actual ReactDOM API name in root type (#22363) 2021-09-20 11:44:21 -04:00
Andrew Clark 79b8fc6670 Implement getServerSnapshot in userspace shim (#22359)
* Convert useSES shim tests to use React DOM

Idea is that eventually we'll run these tests against an actual build of
React DOM 17 to test backwards compatibility.

* Implement getServerSnapshot in userspace shim

If the DOM is not present, we assume that we are running in a server
environment and return the result of `getServerSnapshot`.

This heuristic doesn't work in React Native, so we'll need to provide
a separate native build (using the `.native` extension). I've left this
for a follow-up.

We can't call `getServerSnapshot` on the client, because in versions of
React before 18, there's no built-in mechanism to detect whether we're
hydrating. To avoid a server mismatch warning, users must account for
this themselves and return the correct value inside `getSnapshot`.

Note that none of this is relevant to the built-in API that is being
added in 18. This only affects the userspace shim that is provided
for backwards compatibility with versions 16 and 17.
2021-09-20 08:32:13 -07:00
Andrew Clark 86b3e2461d Implement useSyncExternalStore on server (#22347)
Adds a third argument called `getServerSnapshot`.

On the server, React calls this one instead of the normal `getSnapshot`.
We also call it during hydration.

So it represents the snapshot that is used to generate the initial,
server-rendered HTML. The purpose is to avoid server-client mismatches.
What we render during hydration needs to match up exactly with what we
render on the server.

The pattern is for the server to send down a serialized copy of the
store that was used to generate the initial HTML. On the client, React
will call either `getSnapshot` or `getServerSnapshot` on the client as
appropriate, depending on whether it's currently hydrating.

The argument is optional for fully client rendered use cases. If the
user does attempt to omit `getServerSnapshot`, and the hook is called
on the server, React will abort that subtree on the server and
revert to client rendering, up to the nearest Suspense boundary.

For the userspace shim, we will need to use a heuristic (canUseDOM)
to determine whether we are in a server environment. I'll do that in
a follow up.
2021-09-20 08:31:02 -07:00
Brian Vaughn 57e4d6872f replace-fork: Cleanup after failure if no unstaged changes (#22364) 2021-09-20 11:10:17 -04:00
Andrew Clark 293059e52b replace-fork should not clear uncommitted changes (#22348)
The replace-fork script depends on ESLint to fix the reconciler imports
— `.old` -> `.new` or vice versa. If ESLint crashes, it can leave the
imports in an incorrect state.

As a convenience, @bvaughn updated the script to automatically run
`git checkout -- .` if the ESLint command fails. An unintended
consequence of the strategy is that if the working directory is not
clean, then any uncommitted changes will be lost.

We need a better strategy for this that prevents the accidental loss of
work. One option is to exit early if the working directory is not clean
before you run the script, though that affects the usability of
the script.

An ideal solution would reset the working directory back to whatever
state it was in before the script ran, perhaps by stashing all the
changes and restoring them if the script aborts.

Until we think of something better, I've commmented out the branch.
2021-09-20 10:07:25 -04:00
Andrew Clark 8209de2695 Delete useMutableSource implementation (#22292)
This API was replaced by useSyncExternalStore
2021-09-19 21:11:50 -07:00
Brian Vaughn f50ff357cf DevTools: Fix memory leak via alternate Fiber pointer (#22346) 2021-09-17 12:53:07 -04:00
Brian Vaughn bc9bb87c2b Clear performance marks after measuring (#22345) 2021-09-17 10:46:42 -04:00
Juan 1090ccd019 [DevTools] Enable hook names in standalone app (#22320) 2021-09-17 10:21:54 -04:00
Brian Vaughn f2fd1b80d5 Updated the utfDecodeString() method to avoid call stack exceeded error (#22330) 2021-09-17 09:52:52 -04:00
BIKI DAS b0803f255b VerticalScrollView -> fixed typos (#22341) 2021-09-17 09:05:09 -04:00
Ikko Ashimine a7da457e6b Scheduling profiler: Fix typo in View.js (#22337) 2021-09-17 09:04:51 -04:00
Juan a8cabb5648 [DevTools] Fix runtime error when inspecting an element times out (#22329) 2021-09-15 17:19:10 -04:00
Abhay Gupta e8feb11b62 Fixed issue for better bundles,chunks and workers name in devtools-extensions. (#22322) 2021-09-15 13:51:33 -04:00
Brian Vaughn f4ac680c7a Fixed broken build script --unsafe-partial flag (#22324)
This flag was broken due to a buggy race case in the ncp() command. The fix is amittedly a hack but improves on the existing behavior (of leaving the workspace in a broken state).
2021-09-15 13:32:09 -04:00
Dan Abramov 67222f044c [Experiment] Warn if callback ref returns a function (#22313) 2021-09-15 13:51:39 +01:00
Juan 50263d3273 [DevTools] Add initial APIs for logging instrumentation events under feature flag (#22276) 2021-09-14 11:10:24 -04:00
Ricky 263cfa6ecb [Experimental] Add useInsertionEffect (#21913) 2021-09-14 10:27:09 -04:00
Andrew Clark 806aaa2e21 [useSES shim] Import prefixed native API (#22310)
Until useSyncExternalStore is finalized, the shim should import the
prefixed version (unstable_useSyncExternalStore), which is available
in the experimental builds. That way our early testers can start
using it.
2021-09-13 21:55:18 -07:00
Andrew Clark fd5e01c2e0 [useSES/extra] Reuse old selection if possible (#22307)
When you pass an unmemoized selector to useSyncExternalStoreExtra, we
have to reevaluate it on every render because we don't know whether
it depends on new props.

However, after reevalutating it, we should still compare the result
to the previous selection with `isEqual` and reuse the old one if it
hasn't changed.

Originally I did not implement this, because if the selector changes due
to new props or state, the component is going to have to re-render
anyway. However, it's still useful to return a memoized selection
when possible, because it may be the input to a downstream memoization.

In the test I wrote, the example I chose is selecting a list of
items from the store, and passing the list as a prop to a memoized
component. If the list prop is memoized, we can bail out.
2021-09-13 14:26:41 -07:00
Andrew Clark 33226fadaa Check for store mutations before commit (#22290)
* [useSyncExternalStore] Remove extra hook object

Because we already track `getSnapshot` and `value` on the store
instance, we don't need to also track them as effect dependencies. And
because the effect doesn't require any clean-up, we don't need to track
a `destroy` function.

So, we don't need to store any additional state for this effect. We can
call `pushEffect` directly, and only during renders where something
has changed.

This saves some memory, but my main motivation is because I plan to use
this same logic to schedule a pre-commit consistency check. (See the
inline comments for more details.)

* Split shouldTimeSlice into two separate functions

Lanes that are blocking (SyncLane, and DefaultLane inside a blocking-
by-default root) are always blocking for a given root. Whereas expired
lanes can expire while the render phase is already in progress.

I want to check if a lane is blocking without checking whether it
expired, so I split `shouldTimeSlice` into two separate functions.

I'll use this in the next step.

* Check for store mutations before commit

When a store is read for the first time, or when `subscribe` or
`getSnapshot` changes, during a concurrent render, we have to check
at the end of the render phase whether the store was mutated by
an concurrent event.

In the userspace shim, we perform this check in a layout effect, and
patch up any inconsistencies by scheduling another render + commit.
However, even though we patch them up in the next render, the parent
layout effects that fire in the original render will still observe an
inconsistent tree.

In the native implementation, we can instead check for inconsistencies
right after the root is completed, before entering the commit phase. If
we do detect a mutaiton, we can discard the tree and re-render before
firing any effects. The re-render is synchronous to block further
concurrent mutations (which is also what we do to recover from tearing
bugs that result in an error). After the synchronous re-render, we can
assume the tree the tree is consistent and continue with the normal
algorithm for finishing a completed root (i.e. either suspend
or commit).

The result is that layout effects will always observe a consistent tree.
2021-09-13 08:07:46 -07:00
Konstantin Popov 86c7ca70a9 Fix link (#22296)
Fix link (branch master was renamed to main): 

master -> main
2021-09-12 11:09:53 -04:00
Ricky e73911e715 Clean up my "hard to read" code (#22295) 2021-09-11 15:05:54 -04:00
Brian Vaughn d2f08dd40d DevTools: Add missing param to fetchFromPage() (#22291) 2021-09-10 16:26:46 -04:00
Brian Vaughn 81db4eb1d1 Replaced network.onRequestFinished() caching with network.getHAR() (#22285)
Replaced network.onRequestFinished() caching with network.getHAR() so that we can avoid redundantly (pre) caching JavaScript content. In the event that the HAR log doesn't contain a match, we'll fall back to fetching from the Network (and hoping for a cache hit from that layer).

I've tested both internally (internal Facebook DEV server) and externally (Code Sandbox) and it seems like this approach results in cache hits, so long as DevTools is opened when the page loads. (Otherwise it falls back to fetch().)
2021-09-10 15:11:18 -04:00
salazarm 0fd195f295 update error message to include useLayoutEffect or useEffect on bad e… (#22279)
* update error message to include useLayoutEffect or useEffect on bad effect return

* Update packages/react-reconciler/src/ReactFiberCommitWork.new.js

Co-authored-by: Ricky <rickhanlonii@gmail.com>

* use existing import

Co-authored-by: Ricky <rickhanlonii@gmail.com>
2021-09-10 12:19:51 -04:00
Luna Ruan cb8a50619b [DevTools] Add React Devtools Extension Startup and File Structure to OVERVIEW.md (#22283) 2021-09-09 15:58:27 -07:00
Luna Ruan 43cf06daf9 [DevTools] Fix react-devtools-extension build error and react-devtools-inline's package.json (#22281) 2021-09-09 14:26:13 -07:00
Brian Vaughn 96814e71b2 Revert Suspense cache Thenable.catch() change (#22280)
Reverts part of #22275 (adding .catch() to Thenables in Suspense caches) in response to #22275 (comment).

After taking another look with fresh eyes, I think I see the "uncaught error" issue I initially noticed was in checkForUpdate() (which did not pass an error handler to .then)
2021-09-09 15:26:41 -04:00
Brian Vaughn 225740be48 Add named hooks support to react-devtools-inline (#22263)
This commit builds on PR #22260 and makes the following changes:
* Adds a DevTools feature flag for named hooks support. (This allows us to disable it entirely for a build via feature flag.)
* Adds a new Suspense cache for dynamically imported modules. (This allows a component to suspend while importing an external code chunk– like the hook names parsing code).
* DevTools supports a hookNamesModuleLoaderFunction param to import the hook names module. I wish this could be handles as part of the react-devtools-shared package, but I'm not sure how to configure Webpack (4) to serve the chunk from react-devtools-inline. This seemed like a reasonable workaround.

The PR also contains an additional unrelated change:
* Removes pre-fetch optimization (added in DevTools: Improve named hooks network caching #22198). This optimization was mostly only important for cases where sources needed to be re-downloaded, something which we can now avoid in most cases¹ thanks to using cached responses already loaded by the page. (I tested this locally on Facebook and this change has no negative performance impact. There is still some overhead from serializing the JS through the Bridge but that's constant between the two approaches.)

¹ The case where we don't benefit from cached responses is when DevTools are opened after the page has already loaded certain scripts. This seems uncommon enough that I don't think it justified the added complexity of prefetching.
2021-09-09 15:25:26 -04:00
Andrew Clark 8f96c6b2ac [Bugfix] Prevent infinite update loop caused by a synchronous update in a passive effect (#22277)
* Add test that triggers infinite update loop

In 18, passive effects are flushed synchronously if they are the
result of a synchronous update. We have a guard for infinite update
loops that occur in the layout phase, but it doesn't currently work for
synchronous updates from a passive effect.

The reason this probably hasn't come up yet is because synchronous
updates inside the passive effect phase are relatively rare: you either
have to imperatively dispatch a discrete event, like `el.focus`, or you
have to call `ReactDOM.flushSync`, which triggers a warning. (In
general, updates inside a passive effect are not encouraged.)

I discovered this because `useSyncExternalStore` does sometimes
trigger updates inside the passive effect phase.

This commit adds a failing test to prove the issue exists. I will fix
it in the next commit.

* Fix failing test added in previous commit

The way we detect a "nested update" is if there's synchronous work
remaining at the end of the commit phase.

Currently this check happens before we synchronously flush the passive
effects. I moved it to after the effects are fired, so that it detects
whether synchronous work was scheduled in that phase.
2021-09-09 08:14:30 -07:00
Brian Vaughn 24c2e27256 DevTools Suspense cache cleanup (#22275) 2021-09-09 09:28:17 -04:00
Sebastian Silbermann 4ce89a58da Test bad useEffect return value with noop-renderer (#22258)
* Test bad useEffect return value with noop-renderer

* Use previous "root"-approach

Tests should now be invariant under variants

* Add same test for layout effects
2021-09-08 18:58:53 -04:00
salazarm a3fde23588 Detect subscriptions wrapped in startTransition (#22271)
* Detect subscriptions wrapped in startTransition
2021-09-08 17:01:09 -04:00
Andrew Clark 95d762e406 Remove duplicate test
Accidentally committed two copies of this test during a rebase.
2021-09-08 11:50:21 -04:00
Dan Abramov d4d1dc085d Reorder VARIANT feature flags (#22266)
* Move variant tests up

* Add a comment
2021-09-07 23:28:38 +01:00
Riley Shaw fbce2d5274 Fix #21972: Add onResize event to video elements (#21973)
* Fix #21972: Add `onResize` event to video elements

This is a simple fix for #21972 that adds support for the `onResize` media event.

I created a separate `videoEventTypes` array since I doubt anyone will want to add `onResize` to an audio event. It would simplify the code a bit to just add `resize` to the `mediaEventTypes` array, if that’s preferred.

Pre-commit checklist ([source](https://reactjs.org/docs/how-to-contribute.html#sending-a-pull-request))

 Fork the repository and create your branch from `main`.
 Run `yarn` in the repository root.
 If you’ve fixed a bug or added code that should be tested, add tests!
 Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch TestName` is helpful in development.
 Run `yarn test --prod` to test in the production environment.
 If you need a debugger, run `yarn debug-test --watch TestName`, open chrome://inspect, and press “Inspect”.
 Format your code with prettier (`yarn prettier`).
 Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only check changed files.
 Run the Flow typechecks (`yarn flow`).
 If you haven’t already, complete the CLA.

* Consolidate `videoEventTypes` array into `mediaEventTypes`
2021-09-07 23:28:19 +01:00
Dan Abramov 2f156eafb8 Adjust consoleManagedByDevToolsDuringStrictMode feature flag (#22253) 2021-09-07 19:51:12 +01:00
Andrew Clark cfd8193328 Add useSyncExternalStore to react-debug-tools (#22240)
Adds support for useSyncExternalStore to react-debug-tools, which in
turn adds support for React Devtools.

Test plan: I added a test to ReactHooksInspectionIntegration, based on
existing one for useMutableSource.
2021-09-07 10:58:20 -07:00
Andrew Clark 8e80592a3a Remove state queue from useSyncExternalStore (#22265)
The userspace shim of useSyncExternalStore uses a useState hook because
it's the only way to trigger a re-render. We don't actually use the
queue to store anything, because we read the current value directly
from the store.

In the native implementation, we can schedule an update on the fiber
directly, without the overhead of a queue.
2021-09-07 10:27:01 -07:00
Andrew Clark 06f98c1680 Implement useSyncExternalStore in Fiber (#22239)
This adds an initial implementation of useSyncExternalStore to the
fiber reconciler. It's mostly a copy-paste of the userspace
implementation, which is not ideal but is a good enough starting place.

The main change we'll want to make to this native implementation is to
move the tearing checks from the layout phase to an earlier, pre-commit
phase so that code that runs in the commit phase always observes a
consistent tree.

Follow-ups:

- Implement in Fizz
- Implement in old SSR renderer
- Implement in react-debug-hooks
2021-09-07 10:22:05 -07:00
Andrew Clark 77912d9a05 Wire up the native API for useSyncExternalStore (#22237)
Adds useSyncExternalStore to the internal dispatcher, and exports
the native API from the React package without yet implementing it.
2021-09-07 10:20:24 -07:00
salazarm 031abd24b6 Add warning and test for useSyncExternalStore when getSnapshot isn't cached (#22262)
* add warning and test

* Wrap console error in __DEV__ flag

* prettier
2021-09-07 09:08:33 -07:00
Brian Vaughn e07039bb61 Moved named hooks code (and tests) from react-devtools-extensions to react-devtools-shared (#22260) 2021-09-07 11:44:49 -04:00
Juan abbc79d6fd [DevTools] Only call originalPositionFor once (#22181) 2021-09-07 10:39:55 -04:00
Dan Abramov 771da6e27b Update PULL_REQUEST_TEMPLATE.md 2021-09-07 07:54:34 +01:00
Ryota Murakami d1f51f3453 [package:react-dom] updateREADME's Class Component to Function Component (#21829)
* [package:react-dom] updateREADME's Class Component to Function Component

* Update README.md

Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
2021-09-06 21:23:13 +01:00