Commit Graph

241 Commits

Author SHA1 Message Date
Dominic Gannaway
46f912fd57
[react-core] Add more support for experimental React Scope API (#16621) 2019-08-30 18:27:14 +01:00
Dominic Gannaway
fc80772078
[react-events] Ensure updateEventListeners updates in commit phase (#16540) 2019-08-22 23:58:16 +01:00
Sebastian Markbåge
c80678c760
Add "hydrationOptions" behind the enableSuspenseCallback flag (#16434)
This gets invoked when a boundary is either hydrated or if it is deleted
because it updated or got deleted before it mounted.
2019-08-19 13:26:39 -07:00
Andrew Clark
0bd0c5269f
Upgrade ESLint so we can use JSX Fragment syntax (#16328)
Now that we're using Babel 7, this is the last blocker.
2019-08-09 12:59:02 -07:00
Sunil Pai
b9faa3b092
[act] remove obsolete container element (#16312)
In a previous version of act(), we used a dummy dom element to flush effects. This doesn't need to exist anymore, and this PR removes it. The warning doesn't need to be there either (React will fire a wrong renderer act warning if needed).
2019-08-09 14:26:47 +01:00
Andrew Clark
95767acf83
Bump deps in packages/**/package.json (#16325) 2019-08-08 14:50:11 -07:00
Andrew Clark
85d05b3a4d Bump package.json versions 2019-08-08 14:24:39 -07:00
Sunil Pai
a1dbb852c2 warn if you try to use act() in prod (#16282)
We have behaviour divergence for act() between prod and dev (specifically, act() + concurrent mode does not flush fallbacks in prod. This doesn't affect anyone in OSS yet)

We also don't have a good story for writing tests in prod (and what from what I gather, nobody really writes tests in prod mode).

We could have wiped out act() in prod builds, except that _we_ ourselves use act() for our tests when we run them in prod mode.

This PR is a compromise to all of this. We will log a warning if you try to use act() in prod mode, and we silence it in our test suites.
2019-08-05 13:01:05 -07:00
Dominic Gannaway
42794557ca
[Flare] Tweaks to Flare system design and API (#16264) 2019-08-01 19:08:54 +01:00
Sunil Pai
e6a0473c3c
Warn when rendering tests in concurrent/batched mode without a mocked scheduler (#16207)
Concurrent/Batched mode tests should always be run with a mocked scheduler (v17 or not). This PR adds a warning for the same. I'll put up a separate PR to the docs with a page detailing how to mock the scheduler.
2019-07-30 19:00:18 +01:00
Sunil Pai
d412eec839
[act] flush work correctly without a mocked scheduler (#16223)
Not returning the value of flushPassiveEffects() in flushWork() meant that with async act, we wouldn't flush all work with cascading effects. This PR fixes that oversight, and adds some tests to catch this in the future.
2019-07-26 17:48:42 +01:00
Dominic Gannaway
7ad221126f
[Flare] Ensure Flare components are no-ops for TestRenderer (#16192) 2019-07-24 11:31:33 +01:00
Sunil Pai
c73e1f236f
flush work on exiting outermost act(), with nested act()s from different renderers (#16181)
Given this snippet:
```jsx
    TestRenderer.act(() => {
      TestUtils.act(() => {
        TestRenderer.create(<Effecty />);
      });
    });
```
We want to make sure that all work is only flushed on exiting the outermost act().

Now, naively doing this based on actingScopeDepth would work with a mocked scheduler, where flushAll() would flush all work across renderers.

This doesn't work without mocking the scheduler though; and where flushing work only works per renderer. So we disable this behaviour for a non-mocked scenario. This seems like an ok tradeoff.
2019-07-24 00:20:28 +01:00
Dominic Gannaway
5098891193
[Flare] Redesign core event system (#16163) 2019-07-23 23:46:44 +01:00
Dominic Gannaway
2c4d61e102
Adds experimental fundamental interface (#16049) 2019-07-19 22:20:28 +01:00
Dominic Gannaway
67e3f3fb6e
[Flare] Revise responder event types (#16081) 2019-07-08 14:35:59 +01:00
Sunil Pai
b8f91e6649
[fail] reset IsThisRendererActing correctly (#16042)
* [fail] reset IsThisRendererActing correctly

I missed this in https://github.com/facebook/react/pull/16039. I'd pointed at the wrong previous state, corrupting it in further use. This PR fixes that, and adds a test to make sure it doesn't happen again.

* warn for unacted effects only in strict mode
2019-07-03 03:04:22 +01:00
Sunil Pai
a457e02ae3
allow nested act()s from different renderers (#16039)
* allow nested `act()`s from different renderers

There are usecases where multiple renderers need to oprate inside an act() scope
- ReactDOM.render being used inside another component tree. The parent component will be rendered using ReactTestRenderer.create for a snapshot test or something.
- a ReactDOM instance interacting with a ReactTestRenderer instance (like for the new devtools)

This PR changes the way the acting sigils operate to allow for this. It keeps 2 booleans, one attached to React, one attached to the renderer. act() changes these values, and the workloop reads them to decide what warning to trigger.

I also renamed shouldWarnUnactedUpdates to warnsIfNotActing

* s/ReactIsActing/IsSomeRendererActing and s/ReactRendererIsActing/IsThisRendererActing
2019-07-02 22:20:17 +01:00
Dominic Gannaway
9b0bd43550
[Flare] Re-label Flare flag (#16014) 2019-06-28 01:11:11 +01:00
Dominic Gannaway
8b88ac2592
[Flare] Remove event targets including TouchHitTarget (#16011) 2019-06-27 23:58:48 +01:00
Andrew Clark
4d307de458
Prefix mock Scheduler APIs with _unstable (#15999)
For now this is only meant to be consumed via `act`.
2019-06-26 12:16:08 -07:00
Sunil Pai
fce15f14d3
don't fire missing act() warnings for react-art (#15975)
* use toWarnDev for dom fixture tests

forks toWarnDev from root into fixture/dom, updates tes tests to use it

* disable act() warnings for react-art()

- For 'secondary' renderers like react-act, we don't want to fire missing act() warnings; the wrapping renderer will fire warnings anyway, and when it flushes, it flushes effects *across* renderers.

- I could have used isPrimaryRenderer as the flag, but this is marked as false for react-test-renderer, and we *do* want the warning to fire for it. Hence a new flag.

* add missing dependency `art` to fixtures/dom
2019-06-24 19:18:26 +01:00
Dominic Gannaway
34ce57ae75
[Flare] Refine flow type annotations (#15950) 2019-06-21 12:32:43 +01:00
Dominic Gannaway
720db4cbe6 [Flare] Add useEvent hook implementation (#15927)
* [Flare] Add useEvent hook implementation

Validate hooks have decendent event components

Few fixes and displayName changes

Fix more responder bugs

Update error codes

* Add another test

* Address feedback
2019-06-20 19:12:40 -07:00
Sunil Pai
ff91bfa58c
[act] reset scope depth on synchronous errors (#15937)
* reset scope depth on synchronous errors

we weren't resetting the acting scope depth on sync errors thrown in the callback. this fixes that.

* typos

* add a test to make sure sync error propagate
2019-06-20 13:50:53 +01:00
Dominic Gannaway
689beef6f5
[Flare] Move unstable_createEventComponent to ReactDOM (#15890) 2019-06-18 23:41:00 +01:00
Sunil Pai
9aad17d60c
using the wrong renderer's act() should warn (#15756)
* warn when using the wrong renderer's act around another renderer's updates

like it says. it uses a real object as the sigil (instead of just a boolean). specifically, it uses a renderer's flushPassiveEffects as the sigil. We also run tests for this separate from our main suite (which doesn't allow loading multiple renderers in a suite), but makes sure to run this in CI as well.

* unneeded (and wrong) comment

* run the dom fixture on CI

* update the sigil only in __DEV__

* remove the obnoxious comment

* use an explicit export for the sigil
2019-05-29 22:56:04 +01:00
Sebastian Markbåge
8af1f87929 Rename ReactFiberScheduler -> ReactFiberWorkLoop and extract throwException from Unwind (#15725)
* Rename ReactFiberScheduler to ReactFiberWorkLoop

The scheduling part is mostly extracted out to the scheduler package.

What's remaining is mostly around the loop around each section of work.
I name it something with Work in it because it's very related to the
BeginWork, CompleteWork and UnwindWork sections.

* Extract throwException from UnwindWork

Our throwing works more like algebraic effects in that it's a separate
phase where we find a handler and we later unwind.
2019-05-23 14:24:18 -07:00
Sunil Pai
9c9ea94852
flush only on exiting outermost act() (#15682) 2019-05-21 10:41:24 +01:00
Sunil Pai
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 Clark
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
Andrew Clark
72ca3c60e7
Bump scheduler version to 0.14.0 (#15395) 2019-04-29 18:10:11 -07:00
Dominic Gannaway
aece8119cf
Refactor EventComponent logic + add onOwnershipChange callback (#15354) 2019-04-09 12:47:32 +01:00
Dominic Gannaway
4064ea9fa6
Experimental event API: Support EventComponent onUnmount responder callback (#15335) 2019-04-06 08:16:57 +01:00
Dominic Gannaway
4fbbae8afa
Add full TouchHitTarget hit slop (experimental event API) to ReactDOM (#15308) 2019-04-06 07:51:21 +01:00
Andrew Clark
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 Pai
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 Gannaway
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
Dominic Gannaway
9444a54720
Warn on nested EventTragets in experimental event API (#15287) 2019-04-01 15:47:03 +01:00
Dan Abramov
fb6b50871b Update versions for 16.8.6 2019-03-27 23:58:16 -07:00
Dan Abramov
8e9a013c07 Release 16.8.5 2019-03-22 16:47:59 +00:00
Brian Vaughn
56035dac64
unstable_Profiler -> Profiler (#15172) 2019-03-21 09:18:34 -07:00
Dominic Gannaway
b83e01cade
Adds more scaffolding for experimental event API (#15112)
* Adds more scaffolding for experimental event API
2019-03-20 11:20:17 +00:00
Jared Palmer
2b93d686e3 Add more info to invalid hook call error message (#15139)
* Add more info to invalid hook call error message

* Update other renderers + change call to action

* Update related tests for new hooks error message

* Fix lint errors
2019-03-18 18:22:38 +00:00
Dan Abramov
8d60bd4dc2
[Shallow] Implement setState for Hooks and remount on type change (#15120)
* Throw away old shallow renderer state on type change

This worked in function components but was broken for classes. It incorrectly retained the old instance even if the type was different.

* Remove _previousComponentIdentity

We only needed this because we didn't correctly reset based on type. Now we do so this can go away.

* Use _reset when unmounting

* Use arbitrary componentIdentity

There was no particular reason it was set to element.type. We just wanted to check if something is a render phase update.

* Support Hook state updates in shallow renderer
2019-03-15 22:30:32 +00:00
Brandon Dail
b283d75c17 Support React.memo in ReactShallowRenderer (#14816)
* Support React.memo in ReactShallowRenderer

ReactShallowRenderer uses element.type frequently, but with React.memo
elements the actual type is element.type.type. This updates
ReactShallowRenderer so it uses the correct element type for Memo
components and also validates the inner props for the wrapped
components.

* Allow Rect.memo to prevent re-renders

* Support memo(forwardRef())

* Dont call memo comparison function on initial render

* Fix test

* Small tweaks
2019-03-15 22:17:09 +00:00
Sebastian Silbermann
52c870c8d9 Fix shallow renderer not allowing hooks in forwardRef render functions (#15100)
* test: Add test for shallow + forwardRef + hook

* fix(react-test-renderer): shallow forwardRef hooks
2019-03-15 15:28:34 +00:00
Dominic Gannaway
0c03a47436
Adds experimental event API scaffolding (#15108)
* Adds experimental event API scaffolding
2019-03-14 17:02:42 +00:00
Andrew Clark
1e3b6192b5
Import Scheduler directly, not via host config (#14984)
* Import Scheduler directly, not via host config

We currently schedule asynchronous tasks via the host config. (The host
config is a static/build-time dependency injection system that varies
across different renderers — DOM, native, test, and so on.) Instead of
calling platform APIs like `requestIdleCallback` directly, each renderer
implements a method called `scheduleDeferredCallback`.

We've since discovered that when scheduling tasks, it's crucial that
React work is placed in the same queue as other, non-React work on the
main thread. Otherwise, you easily end up in a starvation scenario where
rendering is constantly interrupted by less important tasks. You need a
centralized coordinator that is used both by React and by other
frameworks and application code. This coordinator must also have a
consistent API across all the different host environments, for
convention's sake and so product code is portable — e.g. so the same
component can work in both React Native and React Native Web.

This turned into the Scheduler package. We will have different builds of
Scheduler for each of our target platforms. With this approach, we treat
Scheduler like a built-in platform primitive that exists wherever React
is supported.

Now that we have this consistent interface, the indirection of the host
config no longer makes sense for the purpose of scheduling tasks. In
fact, we explicitly do not want renderers to scheduled task via any
system except the Scheduler package.

So, this PR removes `scheduleDeferredCallback` and its associated
methods from the host config in favor of directly importing Scheduler.

* Missed an extraneous export
2019-03-06 14:41:45 -08:00
Brian Vaughn
a9aa24ed8d 16.8.4 and changelog 2019-03-05 15:17:42 -08:00