Commit Graph

3128 Commits

Author SHA1 Message Date
Josh Perez 6eebed0535 Shares debugID information across modules (#8097)
Prior to this, React was using a nextDebugID variable that was locally
scoped to both `instantiateReactComponent` and `ReactShallowRenderer`.
This caused problems when the debugIDs would collide, the `itemMap` in
`ReactComponentTreeHook` would be overwritten and tests would fail
with the message "Expected onBeforeMountComponent() parent and
onSetChildren() to be consistent".

This change shares the debugID with both modules thus preventing any
collisions in the future.
2016-10-27 10:31:10 +01:00
Andrew Clark 59c94648c4 PureComponent in Fiber
Passes existing PureComponent tests
2016-10-26 21:02:39 -07:00
Toru Kobayashi 2ef12084e4 [Fiber] Add top level render callbacks into ReactDOMFiber and ReactNoop (#8102)
* [Fiber] Add top level render callbacks into ReactDOMFiber and ReactNoop

* [Fiber] Support multiple render callbacks

* [Fiber] `this` in render callbacks are public instances

* [Fiber] commitLifeCycles move to behind the effectTag check
2016-10-26 13:19:19 -04:00
Andrew Clark d5eff3b0eb [Fiber] String refs and owner tracking (#8099)
* Implement string refs using callback closures

* Merge Fiber type to avoid Flow intersection bugs

Still one remaining type error that I'm not sure how to fix

* Fix Flow issue with an unsafe cast

* Fix missing semicolon

* Add a type import I missed earlier
2016-10-26 14:37:32 +01:00
Toru Kobayashi d49dfe7da4 Fix an argument name of TestUtils.renderIntoDocument (#8104) 2016-10-26 13:44:46 +01:00
Sebastian Markbåge 7bcad0a6aa Merge pull request #8083 from sebmarkbage/fiberfinddomnode
[Fiber] Implement findDOMNode and isMounted
2016-10-26 02:52:20 -04:00
Sebastian Markbåge 51e1937dd6 Merge pull request #8028 from sebmarkbage/nodidupdateforbailout
[Fiber] Don't call componentDidUpdate if shouldComponentUpdate returns false
2016-10-25 18:21:40 -04:00
Sebastian Markbage 46bde58486 Don't call componentDidUpdate if shouldComponentUpdate returns false
This fix relies on the props and state objects being different
to know if we can avoid a componentDidUpdate. This is not a great
solution because we actually want to use the new props/state
object even if sCU returns false. That's the current semantics
and it can actually be important because new rerenders that are
able to reuse props objects are more likely to have the new props
object so we won't be able to quickly bail out next time.
I don't have a better idea atm though.
2016-10-25 15:21:05 -07:00
Sebastian Markbage 8df7afc689 Merge React[DOM/Native]TreeTraversal
These two implementations are identical. Except for some
invariants for some reason.

Since this relies on an implementation detail of the internal
component tree rather than an implementation detail of the
renderer, we might as well merge them and remove the injection.
2016-10-25 14:37:46 -07:00
Sebastian Markbage 8e2d7f8d27 Add tests for findDOMNode on fragment and text
These are new features that aren't covered by existing tests.

It is now possible to use findDOMNode to find a text node.

When a component returns a fragment, it will search to find the
first host component just like element.querySelector does.
2016-10-25 13:59:34 -07:00
Sebastian Markbage d5752aca0d findDOMNode when a component is not yet mounted or unmounted
First we need to check if a component subtree is mounted at all.

If it is, we need to search down the fiber for the first host
node. However, we might be searching the "work in progress"
instead of current.

One realization is that it doesn't matter if we search work in
progress or current if they're the same. They will generally be
the same unless there is an insertion pending or something in
the alternate tree was already deleted. So if we find one of
those cases, we switch to look in the alternate tree instead.
2016-10-25 13:59:34 -07:00
Sebastian Markbage 1914f94041 Handle unmounted and not-yet-inserted subtrees in isMounted
There are two cases where we have a Fiber that is not actually
mounted. Either it is part of a tree that has not yet been
inserted or it is part of a tree that was unmounted.

For the insertion case, we can check the parents to see if there
is any insertion effect pending along the parent path.

For deletions, we can now check if any of the return pointers
is null without actually being the root.
2016-10-25 13:59:34 -07:00
Sebastian Markbage 1376048bd9 Clear effectTag and return pointers after side-effects
This will let us use these pointers to reason about a tree.
Whether if it is "current" or "work in progress".
2016-10-25 13:59:33 -07:00
Sebastian Markbage 2e040fc2c1 Implement isMounted for Fiber
This is the naive implementation that doesn't cover the case
where it has completed but not yet committed. It also doesn't
deal with unmounts since they currently don't clean up the item
in the ReactInstanceMap.
2016-10-25 13:59:33 -07:00
Sebastian Markbage 298d0c3e05 Implement findDOMNode for Fiber
This is the naive implementation that doesn't cover the case where there are
two diverging fibers, or if this tree is unmounted.
2016-10-25 13:59:31 -07:00
Sebastian Markbåge e3131c1d55 Merge pull request #8086 from sebmarkbage/fiberdom
[Fiber] Reorganize files for DOM renderer to make overlap between fiber/stack clearer
2016-10-25 15:56:30 -04:00
Sebastian Markbage a3fb0310ca Reorganize files
This is just moving a bunch of DOM files.

It moves things into dom/stack and dom/fiber respectively. The
dom/stack folder remains split into client/server.

Mainly the shared folder is now my best guess for files that
we can reuse in fiber. Everything else will get forked or
reimplemented.

Also moved the event system out of renderers/shared/stack and
into renderers/shared/shared.
2016-10-25 10:54:14 -07:00
Sebastian Markbåge ea8cf7fbff Delete child when the key lines up but the type doesn't (#8085)
When keys line up in the beginning but the type doesn't
we don't currently delete the child. We need to track that this
fiber is a not a reuse and if so mark the old one for deletion.
2016-10-25 12:51:53 +01:00
Dan Abramov 225325eada Add Fiber Debugger (#8033)
* Build react-noop as a package

This lets us consume it from the debugger.

* Add instrumentation to Fiber

* Check in Fiber Debugger
2016-10-25 08:36:37 +01:00
Sebastian Markbage b26168cadb DefaultEventPluginOrder -> DOMEventPluginOrder
This is not a generic plugin order. It's DOM specific. Unlike
say DefaultBatchingStrategy which is used by Native too.
2016-10-24 19:59:04 -07:00
Sebastian Markbage 4ba8bef19a Split DefaultInjection into two files
This splits DefaultInjection into one with all the properties
and event configuration and a separate one for the things that
are relevant to he stack reconciler.

That way we can reuse the property and event system for Fiber
without pulling in all the other stuff.
2016-10-24 19:44:55 -07:00
Sebastian Markbage b0ccf62ea3 Get rid of ReactInjection
We don't use this indirection. It'll easier to break these apart
without it.
2016-10-24 19:16:56 -07:00
Dan Abramov 265ab83667 Respect state set in componentWillMount() on resuming (#8079)
When resuming creating new instance after resuming work, we should set the `state` on the newly creating instance rather than the old one.
2016-10-25 00:21:56 +01:00
Sebastian Markbåge 06e3b03132 Merge pull request #8078 from sebmarkbage/rmcomment
Remove copypasta comment
2016-10-24 13:49:51 -04:00
Sebastian Markbage 7991a00dcc Remove copypasta comment
Caught by @gaearon
2016-10-24 10:49:10 -07:00
Antti Ahti 954a70e591 Remove deprecated function from tests (#6536)
This has been deprecated since 2013 so it's about time to remove it.
2016-10-24 18:46:38 +01:00
Dan Abramov 14156e56b9 Strip PropTypes checkers in production build (#8066)
* Strip PropTypes in production build

* Revert "Warn if PropType function is called manually (#7132)"

This reverts commit e75e8dcbeb.
2016-10-24 18:43:31 +01:00
Toru Kobayashi 6cdc610bcc [Fiber] Add types for ReactFiber and ReactChildFiber (#8072)
* Add Types for ReactFiber

* Add Types for ReactChildFiber
2016-10-24 14:20:44 +01:00
Sebastian Markbåge 69d725f764 Merge pull request #8055 from sebmarkbage/fiberclassname
Accept className in ReactDOMFiber
2016-10-23 17:04:03 -04:00
Sebastian Markbage 51f1205fb4 Accept className in ReactDOMFiber
This isn't a complete solution to all attributes. It's just that
we run a lot of unrelated unit tests by testing className so
we need it for the tests.
2016-10-22 17:57:33 -07:00
Diego Muracciole 461a74115c Injected Host Component classes are not being considered by the reconciler (#8050)
* Consider Host Component classes when creating a new internal instance

* Remove unused tagToComponentClass & injectComponentClasses from ReactHostComponent
2016-10-22 17:28:37 -05:00
Avinash Kondeti 6810627a91 Fix: updated with new docs links (#8049) 2016-10-22 21:53:52 +01:00
Sebastian Markbage 6e7c89ed8a Quick fix to the return top level problem
This doesn't deal with the fact that work is usually deferred
so this will return null for first render (except in sync tests).
It also doesn't deal with top levels being fragments etc.
It doesn't deal with the host instance type being a wrapper
around the public instance. This needs to be unified with refs
and findDOMNode better.

However, this does expose that we reactComponentExpect and
ReactTestUtils doesn't work very well with Fiber.
2016-10-21 11:58:40 -07:00
Sebastian Markbage 37ca3874af Add unit tests for aborted life-cycles
This tests the life-cycles when work gets aborted.
2016-10-21 11:57:24 -07:00
Sebastian Markbage c862ba719e Fallback to current props if memoizedProps is null
If work has progressed on a state update that gets resumed
because of another state up, then we won't have an new
pendingProps, and we also won't have any memoizedProps because
it got aborted before completing. In that case, we can just
fallback to the current props.

I think that they can't have diverged because the only way they
diverge is if there is new props.

This lets us bail out on state only updates in more cases which
the unit tests reflect.
2016-10-21 11:57:24 -07:00
Sebastian Markbage b72c27ce5d Don't schedule NoWork as the next work
We currently only filter out "NoWork" in the beginning of this
function. If the NoWork root is after the one with work it will
show up in the second loop. There's probably a more efficient
way of doing this but this works for now.

This showed up in this PR because a new unit test gets unblocked
which ends up with this case.
2016-10-21 11:57:24 -07:00
Sebastian Markbage a87ec42f2a Add more life-cycles to Fiber
This refactors the initialization process so that we can share
it with the "module pattern" initialization.

There are a few new interesting scenarios unlocked by this.
E.g. constructor -> componentWillMount -> shouldComponentUpdate
-> componentDidMount when a render is aborted and resumed.
If shouldComponentUpdate returns true then we create a new
instance instead of trying componentWillMount again or
componentWillReceiveProps without being mounted.

Another strange thing is that the "previous props and state"
during componentWillReceiveProps, shouldComponentUpdate and
componentWillUpdate are all the previous render attempt. However,
componentDidMount's previous is the props/state at the previous
commit. That is because the first three can execute multiple
times before a didMount.
2016-10-21 11:57:24 -07:00
Toru Kobayashi a6728f961c [Fiber] Add unit tests for ReactDOMFiber (#8016) 2016-10-21 00:44:23 -04:00
Ben Alpert a8beab3341 Fix captured/bubbled in ReactNativeTreeTraversal (#8019)
Follow-up to #7741. Added a test for RN event bubbling that fails before the fix.
2016-10-20 11:17:06 -07:00
Sebastian Markbåge a5195102d4 [Fiber] Some setState related issues (#8010)
* Use the memoized props/state from the workInProgress

We don't want to use the "current" props/state because if we have
started work, then pause and continue then we'll have the newer
props/state on it already. If it is not a resume, it should be the
same as current.

* Deprioritize setState within a deprioritized tree

Currently we flag the path to a setState as a higher priority
than "offscreen". When we reconcile down this tree we bail out
if it is a hidden node. However, in the case that node is already
completed we don't hit that bail out path. We end up doing the
work immediately which ends up committing that part of the tree
at a higher priority.

This ensures that we don't let a deprioritized subtree get
reconciled at a higher priority.

* Bump idx in unit test

This proves that this number is actually deprioritized.
2016-10-19 13:32:37 -04:00
Toru Kobayashi 3d7869ab0e [Fiber] Add a unit test for ReactTopLevelText (#8001) 2016-10-18 14:39:49 -04:00
Dan Abramov 9bfa45bd2d Update Flow and fix issues (#8006) 2016-10-18 15:26:40 +01:00
Dan Abramov 75367673cf Fix Haste header (#8005) 2016-10-18 14:06:08 +01:00
Sebastian Markbage fae3e5308b Use memoizedState in componentDidUpdate
We forgot to clone this value so it didn't work before.
This is covered by existing tests in ReactDOMProduction.
2016-10-17 16:21:06 -04:00
Sebastian Markbage 685d65bfb6 No duck typing on the root
The root is always a host container.
2016-10-17 16:21:06 -04:00
Sebastian Markbage bc5dfd5358 Break out some Class Component logic into separate module
Refactors the class logic a bit.

I moved scheduleUpdate out into the scheduler since that's where
the scheduling normally happens. I also moved it so that we can
rely on hoisting to resolve the cycle statically.

I moved the updater to a new class component file. I suspect we
will need a bit of space in here since the class initialization
code is quite complex.

The class component dependency is currently fixed in BeginWork
so we can't move complete or commit phase stuff to it. If we need
to, we have to initialize it in the scheduler and pass it to the
other phases.
2016-10-17 16:21:06 -04:00
Sebastian Markbage 9c25538e13 Fix resuming bug
If we abort work but have some completed, we can bail out if
the shouldComponentUpdate returns true. However, then we have
a tree that is low priority. When we bailout we currently use
the "current" tree in this case. I don't think this is right.
I'm not sure why I did that.

Similarly, when we complete we use the "current" props if we
didn't have pending props to do. However, we should be using
the memoized props of that tree if it is a pending work tree.

Added a unit test that covers these two cases.
2016-10-17 16:17:30 -04:00
Sebastian Markbage e59e5b280f Invoke all null ref calls before any new ref calls
This reorganizes the two commit passes so that all host
environment mutations happens before any life-cycles. That means
that the tree is guaranteed to be in a consistent state at that
point so that you can read layout etc.

This also lets us to detach all refs in the same pass so that
when they get invoked with new instances, that happens after it
has been reset.
2016-10-17 16:17:30 -04:00
Sebastian Markbage 3717b71c64 Resolve ref callbacks
During the deletion phase we call detachRefs on any deleted refs.

During the insertion/update phase we call attachRef on class
and host components.

Unfortunately, when a ref switches, we are supposed to call all
the unmounts before doing any mounts. This means that we have to
expact the deletion phase to also include updates in case they
need to detach their ref.
2016-10-17 16:17:30 -04:00
Sebastian Markbage c44c7eaa1b Fire componentDidMount/componentDidUpdate life-cycles
These happen in the commit phase *before* the setState callback.

Unfortunately, we've lost the previous state at this point since
we've already mutated the instance. This needs to be fixed
somehow.
2016-10-17 16:17:30 -04:00