Commit Graph

181 Commits

Author SHA1 Message Date
Brian Vaughn
f546505e4e Support for ReactFeatureFlags.logTopLevelRenders timing (#8687)
Call `console.time` / `console.timeEnd` for the top level component when `ReactFeatureFlags.logTopLevelRenders` is enabled
2017-01-21 09:44:47 -08:00
Sebastian Markbåge
4f8c16a750 Read "current" props from the node instead of the Fiber (#8839)
It's not just events that read the current props. Controlled components
do as well. Since we're no longer updating the Fiber pointer during updates
we have to instead read from the node props to get the current props.

Since this method is no longer just used for events I renamed it.
2017-01-20 23:25:25 -08:00
Sebastian Markbåge
b354db22a9 [Fiber] Compute the Host Diff During Reconciliation (#8607)
* Allow renderers to return an update payload in prepareUpdate

This then gets stored on updateQueue so that the renderer doesn't need to
think about how to store this.

It then gets passed into commitUpdate during the commit phase.

This allows renderers to do the diffing during the time sliced path,
allocate a queue for changes and do only the absolute minimal work to
apply those changes in the commit phase.

If refs update we still schedule and update.

* Hack around the listener problem

* Diff ReactDOMFiber properties in prepareUpdate

We now take advantage of the new capability to diff properties early.
We do this by generating an update payload in the form of an array with
each property name and value that we're about to update.

* Add todo for handling wasCustomComponentTag

* Always force an update to wrapper components

Wrapper components have custom logic that gets applied at the commit phase
so we always need to ensure that we schedule an update for them.

* Remove rootContainerInstance from commitMount

No use case yet and I removed it from commitUpdate earlier.

* Use update signal object in test renderer

* Incorporate 8652 into new algorithm

* Fix comment

* Add failing test for flipping event handlers

This illustrates the problem that happens if we store a pointer to the
Fiber and then choose not to update that pointer when no properties change.
That causes an old Fiber to be retained on the DOM node. Then that Fiber
can be reused by the pooling mechanism which then will mutate that Fiber
with new event handlers, which makes them active before commit.

* Store current props in the RN instance cache and on the DOM node

This represents the current set of event listeners. By not relying on the
Fiber, it allows us to avoid doing any effects in the commit phase when
nothing changes.

This is a bit ugly. Not super happy how this all came together.
2017-01-19 21:56:15 -08:00
Tom Gasson
c77632791f Fix fiber/record-tests to work on windows (slash differences) (#8796) 2017-01-14 21:16:03 -06:00
Dan Abramov
6a488913b9 [Fiber] Fix rendering SVG into non-React SVG tree (#8638)
* Add a test for rendering SVG into a non-React SVG tree

It is failing in Fiber.

* Add a test for rendering HTML into non-React foreignObject

It happens to pass in Fiber.

* Determine root namespace by container namespace, not just tag

A tag alone is not enough to determine the tree namespace.

* Skip the test that exhibits jsdom bug in non-createElement mode

jsdom doesn't give HTML namespace to foreignObject.innerHTML children.
This problem doesn't exist in the browsers.

https://github.com/facebook/react/pull/8638#issuecomment-269349642

We will skip this test in non-createElement mode considering
that non-createElement mounting is effectively dead code now anyway.
2017-01-14 05:11:51 -08:00
Brian Vaughn
be0de3455b Log all Fiber errors w/ component stack (#8756)
A new module has been added (ReactFiberErrorLogger). This logs error information (call stack and component stack) to the console to make errors easier to debug. It also prompts users to use error boundaries if they are not already using them.

In the future, perhaps this will be injectable, enabling users to provide their own handler for custom processing/logging. For the time being, this should help with issues like this / #2461.
2017-01-13 14:45:56 -08:00
Brian Vaughn
2fb07b9502 Added memoization test for interrupted low-priority renders
Test added to verify that a high-priority update can reuse the children from an aborted low-priority update if shouldComponentUpdate returns false.
2017-01-13 13:46:20 -08:00
Brian Vaughn
e17cc98a89 Removed redundant gCC test 2017-01-12 16:58:36 -08:00
Brian Vaughn
4f08884b5d Dedupe missing getChildContext warning by component name 2017-01-12 16:58:36 -08:00
Brian Vaughn
c7f1abade5 Stack and Fiber warn about missing getChildContext method
Previous (probably unintentional) behavior of Stack was to allow components to define childContextTypes without also supplying a getChildContext property. This PR updates Fiber to (temporarily) mimic that behavior. It also adds warning messages to both Fiber and Stack (along with a test).

For the time being, Fiber components with a missing getChildContext method will return the parent context as-is, after warning.
2017-01-12 16:58:36 -08:00
Andrew Clark
199db638c4 Merge pull request #8655 from acdlite/fibermemoizepremptedwork
[Fiber] Move memoization to begin phase
2017-01-12 16:08:02 -08:00
Andrew Clark
9459bad912 Run test script and fix regressions
Fixes the case where there's an uncaught error and the root unmounts.
We implement this by rendering the root as if its child is null. Null is
not usually allowed at the top level, so we need to special case it.
2017-01-12 13:51:22 -08:00
Ben Alpert
54ebcbcd18 Add test for state merging when sCU is false 2017-01-12 12:04:33 -08:00
Andrew Clark
d17b9a13f8 Confirm that a shallow bailout does not drop work in the child
Includes a test that confirms that work that is bailed out before
completing can be reused without dropping the entire subtree.
2017-01-12 11:55:52 -08:00
Andrew Clark
1ed304fa87 Move memoization to begin phase
Currently we update the memoized inputs (props, state) during the
complete phase, as we go back up the tree. That means we can't reuse
work until of its children have completed.

By moving memoization to the begin phase, we can do a shallow bailout,
reusing a unit of work even if there's still work to do in its children.

Memoization now happens whenever a fiber's `child` property is updated;
typically, right after reconciling. It's also updated when
`shouldComponentUpdate` returns false, because that indicates that the
given state and props are equal to the memoized state and props.
2017-01-12 11:55:52 -08:00
Toru Kobayashi
beb5b74c54 [Fiber] Fix to render falsy value as dangerouslySetInnerHTML (#8652)
* [Fiber] Fix to render falsy value as dangerouslySetInnerHTML

* Add more cases and rename test for clarity
2017-01-11 13:19:50 -08:00
Dustan Kasten
2da35fcae8 [Fiber] Implement test renderer (#8628)
* ReactTestRenderer move current impl to stack dir

* ReactTestRenderer on fiber: commence!

* ReactTestRenderer: most non-ref/non-public-instance tests are passing

* Move ReactTestFiberComponent functions from Renderer to Component file

* test renderer: get rid of private root containers and root Maps

* TestRenderer: switch impl based on ReactDOMFeatureFlag.useFiber

* ReactTestRenderer: inline component creation

* ReactTestRenderer: return to pristine original glory (+ Fiber for error order difference)

* TestRendererFiber: use a simple class as TestComponentInstances

* Add `getPublicInstance` to support TestRenderer `createNodeMock`

* Rename files to end. Update for `mountContainer->createContainer` change

* test renderer return same object to prevent unnecessary context pushing/popping

* Fiber HostConfig add getPublicInstance. This should be the identity fn everywhere except the test renderer

* appease flow

* Initial cleanup from sleepy work

* unstable_batchedUpdates

* Stack test renderer: cache nodeMock to not call on unmount

* add public instance type parameter to the reconciler

* test renderer: set _nodeMock when mounted

* More cleanup

* Add test cases for root fragments and (maybe?) root text nodes

* Fix the npm package build

Explicitly require the Stack version by default.
Add a separate entry point for Fiber.

We don't add fiber.js to the package yet since it's considered internal until React 16.

* Relax the ref type from Object to mixed

This seems like the most straightforward way to support getPublicInstance for test renderer.

* Remove accidental newline

* test renderer: unify TestComponent and TestContainer, handle root updates

* Remove string/number serialization attempts since Fiber ensures all textInstances are strings

* Return full fragments in toJSON

* Test Renderer remove TestComponent instances for simple objects

* Update babylon for exact object type syntax

* Use $$typeof because clarity > punching ducks.

* Minor Flow annotation tweaks

* Tweak style, types, and naming

* Fix typo
2017-01-11 11:19:32 -08:00
Dan Abramov
bd23aa2712 Dedupe warnings about refs on functional components (#8739)
* Verify that functional component ref warning is deduplicated

It's not a big problem for string refs because the ref stays the same and the warning code path runs once per mount.

However, it is super annoying for functional refs since they're often written as arrows, and thus the warning fires for every render.

Both tests are currently failing since we're mounting twice, so even the string ref case prints warnings twice.

* Extract the warning condition to the top level

We don't want to run getStackAddendumByID() unless we actually know we're going to print the warning.

This doesn't affect correctness. Just a performance fix.

* Deduplicate warnings about refs on functional components

This fixes the duplicate warnings and adds an additional test for corner cases.

Our goal is to print one warning per one offending call site, when possible.

We try to use the element source for deduplication first because it gives us the exact JSX call site location.

If the element source is not available, we try to use the owner name for deduplication.

If even owner name is unavailable, we try to use the functional component unique identifier for deduplication so that at least the warning is seen once per mounted component.
2017-01-10 09:54:48 -08:00
Dustan Kasten
90294ead4c Warn for callback refs on functional components (Stack + Fiber) (#8635)
* Fiber: warn for refs on SFCs

* Stateless refs: update warning to use component stack

* Warn for function refs (stack and fiber)

* Add owner reference to ref warnings

* Centralize stack ref warnings in ReactRef.attachRef

* Fiber stateless comp ref warning should only do work when necessary

* ReactDebugCurrentFiber maybe FunctionalComponents should act this way instead

* (chore) scripts/fiber/record-tests

* Add component._compositeType to ReactInstance Flow definition

* Don't handle 'stack inside fiber' case in the warning

We don't have a test for it. It's easy to mess it up and print the wrong thing so instead of verifying it I'll just remove this bit.

* Revert the change to getCurrentFiberOwnerName

This happened to work, but it is just a coincidence. This change didn’t really match what the function was supposed to be doing.

I’m not sure what the correct fix would be yet so this commit breaks tests.

* Add component indirection to the tests using owner name

This passes in Stack. It helps ensure we supply the correct owner name.

* Invalid type invariant should read owner from element

This brings the Fiber behavior in line with how Stack does it. The Fiber test was passing accidentally but broke down in more complicated cases (such as when we have an <Indirection> between the owner and the failing element).

Now we can also remove the weird cases from getCurrentFiberOwnerName() that didn't really make sense but helped get the (incomplete) tests pass in the past.

* Fiber should throw on a string ref inside functional component
2017-01-09 15:09:18 -08:00
Brian Vaughn
a682059757 Dont recreate maked context unless unmasked context changes
Doing so can lead to infinite loops if componentWillReceiveProps() calls setState()
2017-01-07 08:53:24 -08:00
Brandon Dail
8095ebaae7 [Fiber] Throw when attempting to unmount at an invalid node (#8688)
* Throw when attempting to unmount at an invalid node

* Remove extra character after invariant
2017-01-05 16:55:17 -08:00
Dan Abramov
ca2c71c0c5 Fix AMD and Brunch issues (#8686)
* Add manual build fixtures

* Inject ReactDOM into ReactWithAddons from ReactWithAddons

We used to read ReactDOM as a global inside ReactAddonsDOMDependenciesUMDShim.
This didn't work in AMD environments such as RequireJS and SystemJS.

Instead, I changed it so that ReactDOM gets injected into ReactWithAddons by ReactDOM itself.
This way we don't have to try to require it (which wouldn't work because AMD doesn't handle circular dependencies well).

This means you have to load ReactDOM first before using ReactDOM-dependent addons, but this was already the case before.

This commit makes all build fixtures pass.

* Memoize ReactDOM to avoid going into require on every access

* Add Brunch fixture

* Inline requires to work around Brunch bug

See #8556 and https://github.com/brunch/brunch/issues/1591#issuecomment-270742503 for context.
This appears to be a Brunch bug but we can keep a temporary fix until the next major.
2017-01-05 13:16:08 -08:00
Andrew Clark
2517a11875 Update refs even if shouldComponentUpdate returns false
Implemented using a Ref effect type.
2017-01-04 12:05:25 -08:00
Brian Vaughn
b27cb2ca2b Merge pull request #8677 from bvaughn/add-callback-validation-to-dom-render
Add callback validation to fiber-based renderers
2017-01-03 14:57:42 -08:00
Brian Vaughn
8fbcd499bd Add callback validation to fiber-based renderers
Moved ReactFiberClassComponent validateCallback() helper function into a standalone util used by both fiber and stack implementations. Validation now happens in ReactFiberUpdateQueue so that non-DOM renderers will also benefit from it.
2017-01-03 12:10:06 -08:00
Andrew Clark
47f92b940f Merge pull request #8658 from acdlite/nullupdatetest
Should not re-render as the result of a null state update
2017-01-03 10:27:32 -08:00
Andrew Clark
ad7bcdf999 Use unbatchedUpdates to opt-out of batching
Reverses the effect of batchedUpdates by resetting the current
batching context.

Does not affect nested updates, which are always deferred regardless
of whether they are inside a batch.
2017-01-03 10:24:27 -08:00
Andrew Clark
b79531eefe No nested updates
We may decide to provide this ability as an escape hatch in the future.
2016-12-30 11:30:40 -08:00
Andrew Clark
5c927b902f Should not re-render as the result of a null state update
Fiber already happens to behave this way; this just adds a test.

TODO: Should we add this feature to Stack, too?
2016-12-29 23:31:48 -08:00
Andrew Clark
79f01b2425 prepareForCommit returns info object to be passed resetAfterCommit
The DOM renderer assumes that resetAfterCommit is called after
prepareForCommit without any nested commits in between. That may not
be the case now that syncUpdates forces a nested update.

To address, this changes the type of prepareForCommit to return a value
which is later passed to resetAfterCommit.
2016-12-29 10:39:24 -08:00
Brian Vaughn
df6ca0e2c1 Merge pull request #8646 from bvaughn/focus-side-effect
Renderers can queue commit effects for initial mount
2016-12-28 15:16:50 -05:00
Brian Vaughn
a10131304b Renderers can schedule commit-time effects for initial mount
The finalizeInitialChildren HostConfig method now utilizes a boolean return type. Renderers can return true to indicate that custom effects should be processed at commit-time once host components have been mounted. This type of work is marked using the existing Update flag.

A new HostConfig method, commitMount, has been added as well for performing this type of work.

This change set is in support of the autoFocus prop.
2016-12-28 15:03:08 -05:00
Dan Abramov
6b73073557 Include owner in invalid element type invariant (#8637) 2016-12-27 08:41:23 -08:00
Dan Abramov
38ed61f4c4 Relax test about rendering top-level null (#8640) 2016-12-27 08:38:24 -08:00
Dan Abramov
119294dcae Validate that update callback is a function (#8639) 2016-12-27 08:38:10 -08:00
Ben Alpert
13980e6536 Fiber: Fix reentrant mounting in synchronous mode (#8623) 2016-12-22 11:34:35 -08:00
Dan Abramov
c978f789cc [Fiber] Push class context providers even if they crash (#8627)
* Push class context providers early

Previously we used to push them only after the instance was available. This caused issues in cases an error is thrown during componentWillMount().

In that case we never got to pushing the provider in the begin phase, but in complete phase the provider check returned true since the instance existed by that point. As a result we got mismatching context pops.

We solve the issue by making the context check independent of whether the instance actually exists. Instead we're checking the type itself.

This lets us push class context early. However there's another problem: we might not know the context value. If the instance is not yet created, we can't call getChildContext on it.

To fix this, we are introducing a way to replace current value on the stack, and a way to read the previous value. This also helps remove some branching and split the memoized from invalidated code paths.

* Add a now-passing test from #8604

Also rename another test to have a shorter name.

* Move isContextProvider() checks into push() and pop()

All uses of push() and pop() are guarded by it anyway.

This makes it more similar to how we use host context.

There is only one other place where isContextProvider() is used and that's legacy code needed for renderSubtree().

* Clarify why we read the previous context

* Use invariant instead of throwing an error

* Fix off-by-one in ReactFiberStack

* Manually keep track of the last parent context

The previous algorithm was flawed and worked by accident, as shown by the failing tests after an off-by-one was fixed.

The implementation of getPrevious() was incorrect because the context stack currently has no notion of a previous value per cursor.

Instead, we are caching the previous value directly in the ReactFiberContext in a local variable.

Additionally, we are using push() and pop() instead of adding a new replace() method.
2016-12-22 10:36:42 -08:00
Dan Abramov
a27e4f3361 [Fiber] Make requestIdleCallback() and requestAnimationFrame() shims async (#8591)
* Add a failing test for recursion check

* Make requestIdleCallback() and requestAnimationFrame() shims async

They no longer need to be sync in tests because we already made DOM renderer sync by default.
This fixes a crash when testing incrementalness in DOM renderer itself.

* Style fix

* Fix lint
2016-12-21 14:04:05 -08:00
Ben Alpert
2a5fe4c2b0 Call refs and lifecycles on indeterminate components (#8614)
This was a bug because of the split between ClassComponent and IndeterminateComponent -- we didn't mark effects or push context when we come from an indeterminate component. Now they behave the same way.

The code is even clumsier than before but I'm pretty worried we'll screw these up in the future if we don't unify the paths.

Not many components exercise this path but Relay containers do so it's noticeable.
2016-12-21 13:51:59 -08:00
Ben Alpert
eca5b1d48e Improve error messages for invalid element types (#8612) 2016-12-21 13:17:34 -08:00
Andrew Clark
15acbaa8e1 Handle errors thrown when committing root
Previously this caused an infinite loop.
2016-12-20 16:20:57 -08:00
Andrew Clark
470da6ea77 Add test for errors in host config while working on failed root
Test for a bug fixed in the previous commit that was causing an
infinite loop.
2016-12-19 18:46:13 -08:00
Andrew Clark
6c26e98ec2 Handle case where host environment throws when working on failed root
Otherwise you fall into an infinite loop where root fails -> host env
throws -> root fails...

This is a worst-case scenario that should only be possible if there's
a bug in the renderer.
2016-12-19 18:06:56 -08:00
Andrew Clark
da4ace152b Remove unmountContainer
Instead, renderers should pass null to updateContainer.
2016-12-19 16:33:25 -08:00
Andrew Clark
c6ccc19095 Use an UpdateQueue for top-level updates
...rather than mutate the pendingProps directly, which throws away any
previously scheduled work.
2016-12-19 16:33:16 -08:00
Andrew Clark
0b37588171 Revert "[Fiber] Queue top-level updates" 2016-12-19 15:32:59 -08:00
Andrew Clark
ddc44b7add Merge pull request #8584 from acdlite/fiberhostrootupdatequeue
[Fiber] Queue top-level updates
2016-12-19 13:56:18 -08:00
Brian Vaughn
1b868cbd71 Don't warn about class component usage of getInitialState if state is also set
We warn about getInitialState() usage in class components because users may have accidentally used it instead of state. If they have also specified state though then we should skip this warning.

Context: https://twitter.com/soprano/status/810003963286163456
2016-12-17 11:16:27 -08:00
Brian Vaughn
a5e728747e Merge pull request #8590 from bvaughn/unexpected-context-pop
`bailoutOnLowPriority` pushes context to mirror complete phase context pop
2016-12-17 07:41:25 -08:00
Dan Abramov
70f704dca6 [Fiber] Nesting validation warnings (#8586)
* (WIP) Nesting warnings

* Remove indirection

* Add a note about namespace

* Fix Flow and make host context required

This makes it easier to avoid accidental nulls.
I also added a test for the production case to avoid regressing because of __DEV__ branches.
2016-12-16 18:57:58 -08:00