Commit Graph

10066 Commits

Author SHA1 Message Date
Andrew Clark 2b509e2c8c [Experimental] API for reading context from within any render phase function (#13139)
* Store list of contexts on the fiber

Currently, context can only be read by a special type of component,
ContextConsumer. We want to add support to all fibers, including
classes and functional components.

Each fiber may read from one or more contexts. To enable quick, mono-
morphic access of this list, we'll store them on a fiber property.

* Context.unstable_read

unstable_read can be called anywhere within the render phase. That
includes the render method, getDerivedStateFromProps, constructors,
functional components, and context consumer render props.

If it's called outside the render phase, an error is thrown.

* Remove vestigial context cursor

Wasn't being used.

* Split fiber.expirationTime into two separate fields

Currently, the `expirationTime` field represents the pending work of
both the fiber itself — including new props, state, and context — and of
any updates in that fiber's subtree.

This commit adds a second field called `childExpirationTime`. Now
`expirationTime` only represents the pending work of the fiber itself.
The subtree's pending work is represented by `childExpirationTime`.

The biggest advantage is it requires fewer checks to bailout on already
finished work. For most types of work, if the `expirationTime` does not
match the render expiration time, we can bailout immediately without
any further checks. This won't work for fibers that have
`shouldComponentUpdate` semantics (class components), for which we still
need to check for props and state changes explicitly.

* Performance nits

Optimize `readContext` for most common case
2018-07-20 16:49:06 -07:00
Dan Abramov 5776fa3fcf Update www warning shim (#13244) 2018-07-20 16:50:43 +01:00
Dan Abramov 3d3506d37d Include Modes in the component stack (#13240)
* Add a test that StrictMode shows up in the component stack

The SSR test passes. The client one doesn't.

* Include Modes in component stack

* Update other tests to include modes
2018-07-19 22:11:59 +01:00
Andrew Clark 71b4e99901 [react-test-renderer] Jest matchers for async tests (#13236)
Adds custom Jest matchers that help with writing async tests:

- `toFlushThrough`
- `toFlushAll`
- `toFlushAndThrow`
- `toClearYields`

Each one accepts an array of expected yielded values, to prevent
false negatives.

Eventually I imagine we'll want to publish this on npm.
2018-07-19 10:26:24 -07:00
Dan Abramov 8121212f0d Fix warning extraction script 2018-07-19 13:04:56 +01:00
Dan Abramov 2a1bc3f74c Format messages in unexpected console.error() test failure 2018-07-19 12:15:01 +01:00
Dan Abramov 2c560cb995 Fix unwinding starting with a wrong Fiber on error in the complete phase (#13237)
* Add a repro case for profiler unwinding

This currently fails the tests due to an unexpected warning.

* Add a regression test for context stack

* Simplify the first test case

* Update nextUnitOfWork inside completeUnitOfWork()

The bug was caused by a structure like this:

    </Provider>
  </div>
</errorInCompletePhase>

We forgot to update nextUnitOfWork so it was still pointing at Provider when errorInCompletePhase threw. As a result, we would try to unwind from Provider (rather than from errorInCompletePhase), and thus pop the Provider twice.
2018-07-19 02:16:10 +01:00
Dan Abramov ead08827d0 Add more flexibility in testing errors in begin/complete phases (#13235)
* Add more flexibility in testing errors in begin/complete phases

* Update too
2018-07-19 00:23:10 +01:00
Andrew Clark e4e58343e4 Move unstable_yield to main export (#13232)
The `yield` method isn't tied to any specific root. Putting this
on the main export enables test components that are not within scope
to yield even if they don't have access to the currently rendering
root instance. This follows the pattern established by ReactNoop.

Added a `clearYields` method, too, for reading values that were yielded
out of band. This is also based on ReactNoop.
2018-07-18 16:10:56 -07:00
Mateusz Burzyński 0e235bb8f7 Removed unused state argument in unsubscribe method of <Subscription /> (#13233) 2018-07-18 13:52:59 -07:00
Dan Abramov 236f608723 Fail tests if toWarnDev() does not wrap warnings in array (#13227)
* Fail tests if toWarn() does not wrap warnings in array

* Fix newly failing tests

* Another fix
2018-07-18 02:38:39 +01:00
Dan Abramov acbb4f93f0 Remove the use of proxies for synthetic events in DEV (#13225)
* Revert #5947 and disable the test

* Fix isDefaultPrevented and isPropagationStopped to not get nulled

This was a bug introduced by #5947. It's very confusing that they become nulled while stopPropagation/preventDefault don't.

* Add a comment

* Run Prettier

* Fix grammar
2018-07-18 00:14:13 +01:00
Nicole Levy 171e0b7d44 Fix “no onChange handler” warning to fire on falsy values ("", 0, false) too (#12628)
* throw warning for falsey `value` prop

* add nop onChange handler to tests for `value` prop

* prettier

* check for falsey checked

* fix tests for `checked` prop

* new tests for `value` prop

* test formatting

* forgot 0 (:

* test for falsey `checked` prop

* add null check

* Update ReactDOMInput-test.js

* revert unneeded change

* prettier

* Update DOMPropertyOperations-test.js

* Update ReactDOMInput-test.js

* Update ReactDOMSelect-test.js

* Fixes and tests

* Remove unnecessary changes
2018-07-17 22:46:43 +01:00
Fumiya Shibusawa 606c30aa5f fixed a typo in commentout in ReactFiberUnwindWork.js (#13172) 2018-07-17 20:21:53 +01:00
Johan Henriksson 9f78913b20 Update prettier (#13205)
* Update Prettier to 1.13.7

* Apply Prettier changes

* Pin prettier version

* EOL
2018-07-17 20:18:34 +01:00
jddxf 6d3e262880 Remove unnecessary typeof checks (#13196)
This aligns with #10351 which removed extra check on `injectInternals`.
2018-07-17 20:18:15 +01:00
Dan Abramov 82c7ca4cca Add component stacks to some warnings (#13218) 2018-07-17 20:15:03 +01:00
Thibault Malbranche 21ac62c77a Fix a portal unmounting crash for renderers with distinct Instance and Container (#13220)
* Fix Portal unmount

Before that change, currentParent is not set as a container even if it should so it break on react-native and probably other custom renderers

* Assert that *ToContainer() methods receive containers

* Add regression tests

* Add comments
2018-07-17 01:35:33 +01:00
Dan Abramov d6a0626b38 Set current fiber during before-mutation traversal (#13219) 2018-07-17 01:11:56 +01:00
Dan Abramov fd410f43fc Protect against passing component stack twice
This is a leftover from #13161 that I forgot to include.
It ensures we don't accidentally write code in the old way and end up passing the stack twice.
2018-07-16 22:47:41 +01:00
Dan Abramov f9358c51c8 Change warning() to automatically inject the stack, and add warningWithoutStack() as opt-out (#13161)
* Use %s in the console calls

* Add shared/warningWithStack

* Convert some warning callsites to warningWithStack

* Use warningInStack in shared utilities and remove unnecessary checks

* Replace more warning() calls with warningWithStack()

* Fixes after rebase + use warningWithStack in react

* Make warning have stack by default; warningWithoutStack opts out

* Forbid builds that may not use internals

* Revert newly added stacks

I changed my mind and want to keep this PR without functional changes. So we won't "fix" any warnings that are already missing stacks. We'll do it in follow-ups instead.

* Fix silly find/replace mistake

* Reorder imports

* Add protection against warning argument count mismatches

* Address review
2018-07-16 22:31:59 +01:00
Dan Abramov 854c953905 Fix matcher tests to be DEV-only 2018-07-16 20:35:43 +01:00
Dan Abramov 467d139101 Enforce presence or absence of component stack in tests (#13215)
* Enforce presence or absence of stack in tests

* Rename expectNoStack to withoutStack

* Fix lint

* Add some tests for toWarnDev()
2018-07-16 20:20:18 +01:00
Andrew Clark 43ffae2d17 Suspending inside a constructor outside of strict mode (#13200)
* Suspending inside a constructor outside of strict mode

Outside of strict mode, suspended components commit in an incomplete
state, then are synchronously deleted in a subsequent commit. If a
component suspends inside the constructor, it mounts without
an instance.

This breaks at least one invariant: during deletion, we assume that
every mounted component has an instance, and check the instance for
the existence of `componentWillUnmount`.

Rather than add a redundant check to the deletion of every class
component, components that suspend inside their constructor and outside
of strict mode are turned into empty functional components before they
are mounted. This is a bit weird, but it's an edge case, and the empty
component will be synchronously unmounted regardless.

* Do not fire lifecycles of a suspended component

In non-strict mode, suspended components commit, but their lifecycles
should not fire.
2018-07-13 11:24:03 -07:00
Dan Abramov 659a29cecf Reorganize how shared internals are accessed (#13201)
* Reorganize how shared internals are accessed

* Update forks.js
2018-07-13 02:45:37 +01:00
Brian Vaughn 58f3b29d91 Added SSR/hydration tests for modes, forwardRef, and Profiler (#13195)
* Added more SSR tests for modes, profiler, and forward-ref
2018-07-12 08:35:21 -07:00
Dan Abramov 1c89cb62fd Use ReactDebugCurrentFrame.getStackAddendum() in element validator (#13198)
Instead of wrapping ReactDebugCurrentFrame.getStackAddendum() call into a custom wrapper inside ReactElementValidator, "teach" the main ReactDebugCurrentFrame.getStackAddendum() to take currently validating element into account.
2018-07-12 16:18:24 +01:00
Dan Abramov e6076ecf48 Remove ad-hoc forks of getComponentName() and fix it (#13197)
* Fix getComponentName() for types with nested $$typeof

* Temporarily remove Profiler ID from messages

* Change getComponentName() signature to take just type

It doesn't actually need the whole Fiber.

* Remove getComponentName() forks in isomorphic and SSR

* Remove unnecessary .type access where we already have a type

* Remove unused type
2018-07-12 07:32:06 -07:00
Philipp Spieß 32f6f258ba Remove event simulation of onChange events (#13176)
* Remove event simulation of onChange events

It’s time to get rid of even more `ReactTestUtils.Simulate`s. In this PR
we remove the event simulation from all onChange tests. To do this, we
have to get a setter to the untracked value/checked props.

All remaining `ReactTestUtils.Simulate` calls are either testing
ReactTestUtils or assert that they do/don't throw.

* Use input instead of change event for all but checkbox, radio, and select
2018-07-12 12:11:35 +01:00
Sen Yang 9ca37f8431 docs: update comments (#13043) 2018-07-11 14:31:48 -07:00
Moti Zilberman f89f25f471 Correct type of ref in forwardRef render() (#13100)
`React$ElementRef<T>` is the type of the ref _instance_ for a component of type T, whereas `React$Ref<T>` is the type of the ref _prop_ for a component of type T, which seems to be the intended type here.
2018-07-11 14:27:46 -07:00
Brian Vaughn 7b99ceabec Deprecate test utils mock component follow up (#13194)
* De-duplicate the mockComponent deprecation warning

* Added fb.me link to mockComponent
2018-07-11 11:56:44 -07:00
Dan Abramov 6ebc8f3c07 Add support for re-entrant SSR stacks (#13181)
* Add failing tests

* Fix re-entrancy in ReactDOMServer
2018-07-11 19:43:54 +01:00
Brian Vaughn d64d1ddb57 Deprecate ReactTestUtils.mockComponent() (#13193)
Deprecate ReactTestUtils.mockComponent()
2018-07-11 10:18:49 -07:00
dongyuwei afd46490d0 update devEngines to include nodejs 10.x (#13190) 2018-07-11 11:46:44 +01:00
Brian Vaughn e79366d549 Link create-subscription doc to GH issue with de-opt explanation (#13187) 2018-07-10 14:00:06 -07:00
Brian Vaughn 1f32d3c6dc Test renderer flushAll method verifies an array of expected yields (#13174) 2018-07-09 09:05:13 -07:00
Dan Abramov 377e1a049e Add a test for SSR stack traces (#13180) 2018-07-09 14:41:48 +01:00
Dan Abramov 96d38d178a Fix concatenation of null to a warning message (#13166) 2018-07-09 13:56:24 +01:00
Brian Vaughn 095dd5049c Add DEV warning if forwardRef function doesn't use the ref param (#13168)
* Add DEV warning if forwardRef function doesn't use the ref param
* Fixed a forwardRef arity warning in another test
2018-07-07 08:11:30 -07:00
Dan Abramov 5662595677 Refactor stack handling (no functional changes) (#13165)
* Refactor ReactDebugCurrentFiber to use named exports

This makes the difference between it and ReactFiberCurrentFrame a bit clearer.

ReactDebugCurrentFiber is Fiber's own implementation.
ReactFiberCurrentFrame is the thing that holds a reference to the current implementation and delegates to it.

* Unify ReactFiberComponentTreeHook and ReactDebugCurrentFiber

Conceptually they're very related.

ReactFiberComponentTreeHook contains implementation details of reading Fiber's stack (both in DEV and PROD).
ReactDebugCurrentFiber contained a reference to the current fiber, and used the above utility.

It was confusing when to use which one. Colocating them makes it clearer what you could do with each method.

In the future, the plan is to stop using these methods explicitly in most places, and instead delegate to a warning system that includes stacks automatically. This change makes future refactorings simpler by colocating related logic.

* Rename methods to better reflect their meanings

Clarify which are DEV or PROD-only.
Clarify which can return null.

I believe the "work in progress only" was a mistake. I introduced it because I wasn't sure what guarantees we have around .return. But we know for sure that following a .return chain gives us an accurate stack even if we get into WIP trees because we don't have reparenting. So it's fine to relax that naming.

* Rename ReactDebugCurrentFiber -> ReactCurrentFiber

It's not completely DEV-only anymore.
Individual methods already specify whether they work in DEV or PROD in their names.
2018-07-07 01:09:41 +01:00
Brandon Dail ebbd221432 Configure react-test-renderer as a secondary (#13164) 2018-07-06 16:04:45 -07:00
Andrew Clark ddc91af795 Decrease nested update limit from 1000 to 50 (#13163)
An infinite update loop can occur when an update is scheduled inside a
lifecycle method, which causes a re-render, which schedules another
update, and so on. Before the Fiber rewrite, this scenario resulted in a
stack overflow.

Because Fiber does not use the JavaScript stack, we maintain our own
counter to track the number of nested, synchronous updates. We throw an
error if the limit is exceeded.

The nested update limit is currently 1000. I chose this number
arbitrarily, certain that there was no valid reason for a component to
schedule so many synchronous re-renders.

I think we can go much lower. This commit decreases the limit to 50. I
believe this is still comfortably above the reasonable number of
synchronous re-renders a component may perform.

This will make it easier for developers to debug infinite update bugs
when they occur.
2018-07-06 15:50:31 -07:00
Andrew Clark 3596e40b39 Fix nested update bug (#13160)
A recent change to the scheduler caused a regression when scheduling
many updates within a single batch. Added a test case that would
have caught this.
2018-07-06 13:55:18 -07:00
Chang Yan 449f6ddd5c create a new FeatureFlags file for test renderer on www (#13159) 2018-07-06 12:55:29 -07:00
Dan Abramov f762b3abb1 Run react-dom SSR import test in jsdom-less environment (#13157) 2018-07-06 16:43:43 +01:00
Brian Vaughn 6f6b560a64 Renamed selfBaseTime/treeBaseTime Fiber attributes to selfBaseDuration/treeBaseDuration (#13156)
This is an unobservable change to all but the (under development) DevTools Profiler plugin. It is being done so that the plugin can safely feature detect a version of React that supports it. The profiler API has existed since the 16.4.0 release, but it did not support the DevTools plugin prior to PR #13058.

Side note: I am not a big fan of the term "base duration". Both it and "actual duration" are kind of awkward and vague. If anyone has suggestions for better names– this is the best time to bikeshed about them.
2018-07-06 08:25:29 -07:00
Dan Abramov 1386ccddd8 Fix ReferenceError when requestAnimationFrame isn't defined (#13152)
* Make the test fail

* Fix rAF detection to avoid a ReferenceError
2018-07-05 19:42:45 +01:00
Dan Abramov f5779bbc10 Run server rendering test on bundles (#13153) 2018-07-05 19:42:22 +01:00
Brian Vaughn 9faf389e79 Reset profiler timer correctly after errors (#13123)
* Reset ReactProfilerTimer's DEV-only Fiber stack after an error

* Added ReactNoop functionality to error during "complete" phase

* Added failing profiler stack unwinding test

* Potential fix for unwinding time bug

* Renamed test

* Don't record time until complete phase succeeds. Simplifies unwinding.

* Expanded ReactProfilerDevToolsIntegration-test coverage a bit

* Added unstable_flushWithoutCommitting method to noop renderer

* Added failing multi-root/batch test to ReactProfiler-test

* Beefed up tests a bit and added some TODOs

* Profiler timer differentiates between batched commits and in-progress async work

This was a two-part change:
1) Don't count time spent working on a batched commit against yielded async work.
2) Don't assert an empty stack after processing a batched commit (because there may be yielded async work)

This is kind of a hacky solution, and may have problems that I haven't thought of yet. I need to commit this so I can mentally clock out for a bit without worrying about it. I will think about it more when I'm back from PTO. In the meanwhile, input is welcome.

* Removed TODO

* Replaced FiberRoot map with boolean

* Removed unnecessary whitespace edit
2018-07-05 11:38:06 -07:00