Commit Graph
282 Commits
Author SHA1 Message Date
Andrew ClarkandGitHub 6b5deeed50 [Events] Add support for events that are both user-blocking and continuous (#15811)
* [Events] Add EventPriority enum

React DOM's DispatchConfig for synthetic events has an `isDiscrete`
field that affects how updates triggered by an event are scheduled.
Events are either discrete or continuous.

This commit adds an additional type of configuration where an event
has user-blocking priority, but is not discrete. E.g. updates triggered
by hover are more important than the default, but they don't need to
be processed serially. Because there are now three types of event
priority instead of two, I've replaced the `isDiscrete` boolean with an
enum: `eventPriority`.

This commit implements the new enum value but does not change any
behavior. I'll enable it behind a feature flag in the next commit.

I've only implemented this in the legacy event system. I'll leave Flare
for a follow-up.

* enableUserBlockingEvents feature flag

Adds a feature flag to increase the priority of events like `mouseover`,
without making them discrete.
2019-06-04 13:35:52 -07:00
James IdeandChristoph Nakazawa 07da821bfd [react-native] Rewrite Haste imports in RN shims and add .fb.js extension (#15786)
This commit is a follow-up to https://github.com/facebook/react/pull/15604, which explains more of the rationale behind moving React Native to path-based imports and the work needed in the React repository. In that linked PR, the generated renderers were updated but not the shims; this commit updates the shims.

The problem is that FB needs a different copy of the built renderers than the OSS versions so we need a way for FB code to import different modules than in OSS. This was previously done with Haste, but with the removal of Haste from RN, we need another mechanism. Talking with cpojer, we are using a `.fb.js` extension that Metro can be configured to prioritize over `.js`.

This commit generates FB's renderers with the `.fb.js` extension and OSS renderers with just `.js`. This way, FB can internally configure Metro to use the `.fb.js` implementations and OSS will use the `.js` ones, letting us swap out which implementation gets bundled.

Test Plan: Generated the renderers and shims with `yarn build` and then verified that the generated shims don't contain any Haste-style imports. Copied the renderers and shims into RN manually and launched the RNTester app to verify it loads end-to-end. Added `.fb.js` to the extensions in `metro.config.js` and verified that the FB-specific bundles loaded.
2019-06-03 15:58:31 +01:00
Dominic GannawayandGitHub 287ef30bba [Flare] Deeply prevent default on anchor elements (#15750) 2019-05-28 12:46:07 +01:00
Dominic GannawayandGitHub b962adfc2b [Flare] event component displayName is now mandatory (#15717) 2019-05-23 01:29:07 +01:00
Dominic GannawayandGitHub 121acae090 Flare: simplify dispatchEvent discrete argument (#15694) 2019-05-21 16:06:17 +01:00
Sebastian MarkbågeandGitHub 9c6de716d0 Add withSuspenseConfig API (#15593)
* Add suspendIfNeeded API and a global scope to track it

Adds a "current" suspense config that gets applied to all updates scheduled
during the current scope.

I suspect we might want to add other types of configurations to the "batch"
so I called it the "batch config".

This works across renderers/roots but they won't actually necessarily go
into the same batch.

* Add the suspenseConfig to all updates created during this scope

* Compute expiration time based on the timeout of the suspense config

* Track if there was a processed suspenseConfig this render pass

We'll use this info to suspend a commit for longer when necessary.

* Mark suspended states that should be avoided as a separate flag

This lets us track which renders we want to suspend for a short time vs
a longer time if possible.

* Suspend until the full expiration time if something asked to suspend

* Reenable an old test that we can now repro again

* Suspend the commit even if it is complete if there is a minimum delay

This can be used to implement spinners that don't flicker if the data
and rendering is really fast.

* Default timeoutMs to low pri expiration if not provided

This is a required argument in the type signature but people may not
supply it and this is a user facing object.

* Rename to withSuspenseConfig and drop the default config

This allow opting out of suspending in some nested scope.

A lot of time when you use this function you'll use it with high level
helpers. Those helpers often want to accept some additional configuration
for suspense and if it should suspend at all. The easiest way is to just
have the api accept null or a suspense config and pass it through. However,
then you have to remember that calling suspendIfNeeded has a default.

It gets simpler by just saying tat you can pass the config. You can have
your own default in user space.

* Track the largest suspense config expiration separately

This ensures that if we've scheduled lower pri work that doesn't have a
suspenseConfig, we don't consider its expiration as the timeout.

* Add basic tests for functionality using each update mechanism

* Fix issue when newly created avoided boundary doesn't suspend with delay

* Add test for loading indicator with minLoadingDurationMs option
2019-05-16 16:51:18 -07:00
Dominic GannawayandGitHub 1160b37691 Event API: Add responder allowMultipleHostChildren flag (#15646) 2019-05-16 19:03:38 +01:00
Sunil PaiandGitHub d278a3ff8b act() - s / flushPassiveEffects / Scheduler.unstable_flushWithoutYielding (#15591)
* s/flushPassiveEffects/unstable_flushWithoutYielding

a first crack at flushing the scheduler manually from inside act(). uses unstable_flushWithoutYielding(). The tests that changed, mostly replaced toFlushAndYield(...) with toHaveYielded(). For some tests that tested the state of the tree before flushing effects (but still after updates), I replaced act() with bacthedUpdates().

* ugh lint

* pass build, flushPassiveEffects returns nothing now

* pass test-fire

* flush all work (not just effects), add a compatibility mode

of note, unstable_flushWithoutYielding now returns a boolean much like flushPassiveEffects

* umd build for scheduler/unstable_mock, pass the fixture with it

* add a comment to Shcduler.umd.js for why we're exporting unstable_flushWithoutYielding

* run testsutilsact tests in both sync/concurrent modes

* augh lint

* use a feature flag for the missing mock scheduler warning

I also tried writing a test for it, but couldn't get the scheduler to unmock. included the failing test.

* Update ReactTestUtilsAct-test.js

- pass the mock scheduler warning test,
- rewrite some tests to use Scheduler.yieldValue
- structure concurrent/legacy suites neatly

* pass failing tests in batchedmode-test

* fix pretty/lint/import errors

* pass test-build

* nit: pull .create(null) out of the act() call
2019-05-16 17:12:36 +01:00
Andrew ClarkandGitHub b899819e77 Use dynamic flag in test renderer in www (#15662)
Uses a dynamic flag in www's test renderer build so we can condtionally
disable the passive effects bugfix. Matches the dynamic flag used in
the www React DOM build.
2019-05-15 14:55:50 -07:00
Andrew ClarkandGitHub d34b457ce2 Feature flag to revert #15650 (#15659)
PR #15650 is a bugfix but it's technically a semantic change that could
cause regressions. I don't think it will be an issue, since the
previous behavior was both broken and incoherent, but out of an
abundance of caution, let's wrap it in a flag so we can easily revert
it if necessary.
2019-05-15 13:38:06 -07:00
Andrew ClarkandGitHub 83fc258f29 Remove <ConcurrentMode /> (#15532)
Use createSyncRoot instead.
2019-05-13 16:10:00 -07:00
Andrew ClarkandGitHub 862f499fac Add Batched Mode (#15502)
* Add Batched Mode

React has an unfortunate quirk where updates are sometimes synchronous
-- where React starts rendering immediately within the call stack of
`setState` — and sometimes batched, where updates are flushed at the
end of the current event. Any update that originates within the call
stack of the React event system is batched. This encompasses most
updates, since most updates originate from an event handler like
`onClick` or `onChange`. It also includes updates triggered by lifecycle
methods or effects. But there are also updates that originate outside
React's event system, like timer events, network events, and microtasks
(promise resolution handlers). These are not batched, which results in
both worse performance (multiple render passes instead of single one)
and confusing semantics.

Ideally all updates would be batched by default. Unfortunately, it's
easy for components to accidentally rely on this behavior, so changing
it could break existing apps in subtle ways.

One way to move to a batched-by-default model is to opt into Concurrent
Mode (still experimental). But Concurrent Mode introduces additional
semantic changes that apps may not be ready to adopt.

This commit introduces an additional mode called Batched Mode. Batched
Mode enables a batched-by-default model that defers all updates to the
next React event. Once it begins rendering, React will not yield to
the browser until the entire render is finished.

Batched Mode is superset of Strict Mode. It fires all the same warnings.
It also drops the forked Suspense behavior used by Legacy Mode, in favor
of the proper semantics used by Concurrent Mode.

I have not added any public APIs that expose the new mode yet. I'll do
that in subsequent commits.

* Suspense in Batched Mode

Should have same semantics as Concurrent Mode.

* Use RootTag field to configure type of root

There are three types of roots: Legacy, Batched, and Concurrent.

* flushSync should not flush batched work

Treat Sync and Batched expiration times separately. Only Sync updates
are pushed to our internal queue of synchronous callbacks.

Renamed `flushImmediateQueue` to `flushSyncCallbackQueue` for clarity.
2019-05-13 14:30:39 -07:00
Dominic GannawayandGitHub fec74f99da Event API: ensure preventDefault works for nested targets (#15633) 2019-05-13 13:45:48 +01:00
Andrew ClarkandGitHub edfedf3ae9 Fork ReactSharedInternals for UMD builds (#15617) 2019-05-10 13:51:39 -07:00
Andrew Clark 39ef609e7c Update test to fix CI 2019-05-10 11:12:24 -07:00
Dominic GannawayandGitHub e33e32db04 Event API: normalize event timeStamp property to be in event system (#15598) 2019-05-09 16:05:25 +01:00
Dominic GannawayandGitHub 51e66cf9fa Experimental Event API: reduce code size of event modules (#15590) 2019-05-08 19:09:32 +01:00
Dominic GannawayandGitHub ec6691a687 Event API: remove isTargetDirectlyWithinEventComponent (#15546) 2019-04-30 17:38:48 +01:00
Dominic GannawayandGitHub bd88982fbf Event API: use capture for all event listeners using experimental responder system (#15526) 2019-04-30 11:40:45 +01:00
Nathan SchlossandAndrew Clark 43c4e5f348 Add method for forcing a lower framerate 2019-04-29 15:51:58 -07:00
Dominic GannawayandGitHub d1f667acc0 Event API: follow up fixes for FocusScope + context changes (#15496) 2019-04-25 20:10:33 +01:00
FUJI GoroandChristoph Nakazawa 1eb2b892df give canUseDOM with a possibility to be a constant (#14194)
https://webpack.js.org/plugins/define-plugin/

Webpack's DefinePlugin has the ability to replace `typeof expr` to a constant in compile-time, which should lead to better dead-code-elimination.
2019-04-25 11:28:53 +01:00
shubhamandChristoph Nakazawa de26d6dd36 typo fix (#15493)
changed ReactResponderContext.dispatchEvent otpions keys to options.
2019-04-25 09:37:35 +01:00
Dominic GannawayandGitHub 64e3da286f Event API: Add FocusScope surface (#15487) 2019-04-25 02:01:09 +01:00
Dominic GannawayandGitHub fa2fa3564d Experimental event API: adds context.isTargetDirectlyWithinEventComponent (#15481) 2019-04-24 11:02:47 +01:00
Dominic GannawayandGitHub d3af2f2a5d Experimental Event API: add event component mount phase callback (#15480) 2019-04-24 10:41:24 +01:00
Dominic GannawayandGitHub 017d6f14b7 Experimental Event API: add rootEventTypes support to event responders (#15475)
* Adds rootEventTypes
2019-04-23 19:55:50 +01:00
Dominic GannawayandGitHub 784ebd8fa9 Experimental event API: rework the propagation system for event components (#15462) 2019-04-23 11:50:48 +01:00
Dominic GannawayandGitHub 9ebe1768a8 Experimental Event API: Redesign event responder propagation (#15408)
* Event API: Redesign event instance propagation
2019-04-13 20:37:39 +01:00
Dominic GannawayandGitHub 543353a043 Experimental Event API: Remove "listener" from event objects (#15391) 2019-04-12 11:53:40 +01:00
Andrew ClarkandGitHub 9055e31e5c Replace old Fiber Scheduler with new one (#15387)
The new Fiber Scheduler has been running in Facebook for several days
without issues. Let's switch to it.
2019-04-11 19:15:34 -07:00
Dominic GannawayandGitHub 9672cf621b Experimental Event API: adds stopPropagation by default to Press (#15384) 2019-04-11 20:00:20 +01:00
Dominic GannawayandGitHub dd9cef9fc0 Experimental Event API: Add targets and responder utility method for finding targets (#15372) 2019-04-10 18:52:34 +01:00
Dominic GannawayandGitHub c64b330032 Move EventTypes to ReactTypes (#15364) 2019-04-10 09:55:56 +01:00
Dominic GannawayandGitHub aece8119cf Refactor EventComponent logic + add onOwnershipChange callback (#15354) 2019-04-09 12:47:32 +01:00
Ricky VetterandGitHub 745baf2e06 Provide new jsx transform target for reactjs/rfcs#107 (#15141)
* adding jsx function

* add more feature flag defaults

* flip ReactElement order back
2019-04-07 15:02:34 -04:00
Dominic GannawayandGitHub 4fbbae8afa Add full TouchHitTarget hit slop (experimental event API) to ReactDOM (#15308) 2019-04-06 07:51:21 +01:00
Dominic GannawayandGitHub b93a8a9bb8 Experimental event API: refactor responder modules for lifecycle inclusion (#15322) 2019-04-04 23:28:23 +01:00
Dan AbramovandGitHub e5c59359c4 Prevent bundling of Node polyfills when importing TestUtils/TestRenderer (#15305) 2019-04-03 16:12:31 +01:00
Dominic GannawayandGitHub 89064fe68d Adds displayName to EventComponent and EventTarget (#15268)
* Adds displayName to EventComponent and EventTarget
2019-04-03 12:24:25 +01:00
Andrew ClarkandGitHub 4d5cb64aa2 Rewrite ReactFiberScheduler for better integration with Scheduler package (#15151)
* Rewrite ReactFiberScheduler

Adds a new implementation of ReactFiberScheduler behind a feature flag.
We will maintain both implementations in parallel until the new one
is proven stable enough to replace the old one.

The main difference between the implementations is that the new one is
integrated with the Scheduler package's priority levels.

* Conditionally add fields to FiberRoot

Some fields only used by the old scheduler, and some by the new.

* Add separate build that enables new scheduler

* Re-enable skipped test

If synchronous updates are scheduled by a passive effect, that work
should be flushed synchronously, even if flushPassiveEffects is
called inside batchedUpdates.

* Passive effects have same priority as render

* Revert ability to cancel the current callback

React doesn't need this anyway because it never schedules callbacks if
it's already rendering.

* Revert change to FiberDebugPerf

Turns out this isn't neccessary.

* Fix ReactFiberScheduler dead code elimination

Should initialize to nothing, then assign the exports conditionally,
instead of initializing to the old exports and then reassigning to the
new ones.

* Don't yield before commit during sync error retry

* Call Scheduler.flushAll unconditionally in tests

Instead of wrapping in enableNewScheduler flag.
2019-04-02 15:49:07 -07:00
Sunil PaiandGitHub aed0e1c30c await act(async () => ...) (#14853)
This took a while, but I'm happy I went through it. Some key moments - recursively flushing effects, flushing microtasks on each async turn, and my team's uncompromising philosophy on code reuse. Really happy with this. I still want to expand test coverage, and I have some more small related todos, but this is good to land. On to the next one. 

Soundtrack to landing this - https://open.spotify.com/track/0MF8I8OUo8kytiOo8aSHYq?si=gSWqUheKQbiQDXzptCXHTg

* hacked up act(async () => {...})

* move stuff around

* merge changes

* abstract .act warnings and stuff. all renderers. pass all tests.

* move testutils.act back into testutils

* move into scheduler, rename some bits

* smaller bundle

* a comment for why we don't do typeof === 'function'

* fix test

* pass tests - fire, prod

* lose actContainerElement

* tighter

* write a test for TestRenderer

it's an odd one, because not only does sync act not flush effects correctly, but the async one does (wut). verified it's fine with the dom version.

* lint

* rewrote to move flushing logic closer to the renderer

the scheduler's `flushPassiveEffects` didn't work as expected for the test renderer, so I decided to go back to the hack (rendering a dumb container) This also makes reactdom not as heavy (by a few bytes, but still).

* move it around so the delta isn't too bad

* cleanups

fix promise chaining
propagate errors correctly
test for thenable the 'right' way
more tests!
tidier!
ponies!

* Stray comment

* recursively flush effects

* fixed tests

* lint, move noop.act into react-reconciler

* microtasks when checking if called, s/called/calledLog, cleanup

* pass fb lint

we could have globally changed our eslint config to assume Promise is available, but that means we expect a promise polyfill on the page, and we don't yet. this code is triggered only in jest anyway, and we're fairly certain Promise will be available there. hence, the once-off disable for the check

* shorter timers, fix a test, test for Promise

* use global.Promise for existence check

* flush microtasks

* a version that works in browsers (that support postMessage)

I also added a sanity fixture inside fixtures/dom/ mostly for me.

* hoist flushEffectsAndMicroTasks

* pull out tick logic from ReactFiberScheduler

* fix await act (...sync) hanging

- fix a hang when awaiting sync logic
- a better async/await test for test renderer

* feedback changes

- use node's setImmediate if available
- a warning if MessageChannel isn't available
- rename some functions

* pass lint/flow checks (without requiring a Promise polyfill/exclusion)

* prettier

the prettiest, even.

* use globalPromise for the missed await warning

* __DEV__ check for didWarnAboutMessageChannel

* thenables and callbacks instead of promises, pass flow/lint

* tinier. better.

- pulled most bits out of FiberScheduler
- actedUpdates uses callbacks now

* pass build validation

* augh prettier

* golfing 7 more chars

* Test that effects are not flushed without also flushing microtasks

* export doesHavePendingPassiveEffects, nits

* createAct()

* dead code

* missed in merge?

* lose the preflushing bits

* ugh prettier

* removed `actedUpdates()`, created shared/actingUpdatesScopeDepth

* rearrange imports so builds work, remove the hack versions of flushPassiveEffects

* represent actingUpdatesScopeDepth as a tuple [number]

* use a shared flag on React.__SECRET...

* remove createAct, setup act for all relevant renderers

* review feedback

shared/enqueueTask

import ReactSharedInternals from 'shared/ReactSharedInternals';

simpler act() internals

ReactSharedInternals.ReactShouldWarnActingUpdates

* move act() implementation into createReactNoop

* warnIfNotCurrentlyActingUpdatesInDev condition check order
2019-04-02 22:33:31 +01:00
Dominic GannawayandGitHub 6a1e6b2f78 Experimental event API: loosen EventTarget constraints and warnings (#15292)
* Remove warning for event targets being direct children of event component

* Addressed feedback and added more test coverage + warnings
2019-04-02 19:49:28 +01:00
Sebastian MarkbågeandGitHub c7a2dce50a Disable JS urls at build level for www (#15230)
This will be on by default in open source for the next major.
2019-03-28 14:36:36 -07:00
Dan Abramov fb6b50871b Update versions for 16.8.6 2019-03-27 23:58:16 -07:00
Brian VaughnandGitHub d8cb10f11f Enabled warnAboutDeprecatedLifecycles flag by default (#15186) 2019-03-27 16:30:49 -07:00
Dan Abramov 8e9a013c07 Release 16.8.5 2019-03-22 16:47:59 +00:00
Andrew Clark b1a56abd6a Fork ReactFiberScheduler with feature flag
Adds a feature flag `enableNewScheduler` that toggles between two
implementations of ReactFiberScheduler. This will let us land changes in
master while preserving the ability to quickly rollback.

Ideally this will be a short-lived fork. Once we've tested the new
scheduler for a week or so without issues, we will get rid of it. Until
then, we'll need to maintain two parallel implementations and run tests
against both of them. We rarely land changes to ReactFiberScheduler, so
I don't expect this will be a huge burden.

This commit does not implement anything new. The flag is still off and
tests run against the existing implementation.

Use `yarn test-new-scheduler` to run tests against the new one.
2019-03-20 16:28:33 -07:00
Dominic GannawayandGitHub b83e01cade Adds more scaffolding for experimental event API (#15112)
* Adds more scaffolding for experimental event API
2019-03-20 11:20:17 +00:00
Dominic GannawayandGitHub 55cc921c5d Adds react-events package for internal testing (#15150)
* Adds react-events package for internal testing
2019-03-19 15:12:45 +00:00