I'll plan to change all of our console.error and component-tree expects to expectDev. It's a little annoying that we need to make sure tests don't throw (see my change to normalizeCodeLocInfo) but any alternative would seem to require two separate test runs or a much more cumbersome syntax.
* Handles risky callbacks on setState. Fixes#8238
* Updates try-catch to cover `callback` when context is not present.
* Updates code to trapErrors instead of swallowing them.
* Fixes flow errors
* Incorporates review comments
* Traps only the first error.
Removes `callbackWasCalled` and updates fiber tests.
I came up with a contrived case of where nested controlled events could
fire within the same batch - but on different targets.
I think we came to the conclusion that controlled values typically cannot
use preventDefault so it is ok that they don't flush until after the event
has finished. So therefore we accumulate a queue of all the nested targets
within a batch and then restore state on all of them.
I'm still skeptical that this is the correct way to do controlled values.
The reason we have to do them in a single event loop is because when you
type, the sequence of values that get accepted or not can matter. I wonder
if there is a scenario we can come up with where you can fire multiple
inner events in an event loop and end up with batching causing problems.
This effectively just reimplements asap again but with no allocations for
a single target and no closure allocations.
* Use _hostContainerInfo to track test renderer options
The transaction is not available when unmounting or updating the
instance, so we track it using _hostContainerInfo
* Throw if hostContainerInfo is not populated in getPublicInstance
* Linting fixes
* Remove transaction from ref lifecycle code path
We don't need to pass the transaction around anymore since we store the
test options on _hostContainerInfo instead
* Remove unused argument
If a controlled target fires within another controlled event, we should not
restore it until we've fully completed the event. Otherwise, if someone
reads from it afterwards, they'll get the restored value.
Not super happy with this particular solution.
This reverts commit a878c3056d.
The previous stuff that this builds on didn't successfully land fully. Since I
want to measure this in isolation, I'll revert this for now.
This just reads events from the props instead of storing them in a
listener back.
I had to rewrite a bunch of tests to cover this model.
I removed the tests that just test the adding and removing over listeners
since there is no equivalent behavior anymore.
This reverts the implementation in 33325ad009.
I didn't mean to merge the implementation since it is incorrect and incomplete.
I meant to just merge the unit test.
* Ensure that we're listening to all onChange dependencies for controlled inputs
When there is no onChange event handler, we should still listen to it to
ensure controlled values get reset.
There is warning associated with this but the prod behavior should still be
respected.
* Rerun tests
* Use explicit pass for restoring controlled state instead of asap
This gets rid of the first class ReactUpdates.asap scheduling. Instead of
scheduling a first class function to invoke later, I introduce an explicit
phase for restoring controlled state after dispatching events.
We assume that the deepest event target is the thing that needs its state
restored.
* Drop special cases for onChange in wrappers
We're now not using anything special about onChange handling in the
wrappers. Yay!
* Attempt to fix ReactDOMTextComponent test in Fiber
Obviously, some tests pass but the reconciliation is still incomplete on this in Fiber.
Those changes just ignore reconciliation Comments while asserting (this fixes 2 tests already) but now shows that Fiber lacks some reconciliation features.
* Transmit a parentInstance to commitTextUpdate
This is done in case a Node#normalize() was performed on the parent instance and that the TextInstance got desolidarized from the parent. We provide the parent known by the parent Fiber to reattach the DOM node in this case.
* Added a more complex case around split nodes
This test does not assume one split node substitution alone but also some non-split nodes.
* Fiber supports split text nodes
This is done by suppressing nodes appearing during the split. this is based by comparing against the old value known by the Fiber.
* Simplify siblings cleaning in commitTextUpdate
No need to assert instanceof Text since the length comparator will work correctly.
* Ensure non-text nodes won't be removed
* Fix flow for Fiber Text reconciliation additions
Mostly define types as optionals. Respects the strict DOM API around Node & Element.
* Append at any stack stage only if necessary
The direct parent of the TextNode fiber may not contain the host node. We have to go through the hierarchy. However, since this work may be expensive, we only do it if absolutely necessary!
* Use tag & ReactTypeOfWork to find an HostComponent
* Addfailing scenario when running Node.normalize()
It happens when non-text-elements are added in the mix. @sebmarkbage seems to have an idea on how to fix it. This is just a repro of the bug!
* Register failing/passing fiber tests
This gets rid of the global flag on if something has listened to onSelect
and instead reads the isListening map if all the events are covered.
This is required if we want to attach events locally at roots.
Could be slower perf wise to handle events. An alternative solution would
be to attach a special flag on the listener map for the document so we
don't have to check the full dependency list.
However, my favorite solution would be to just eagerly attach all event
listeners (except maybe wheel). Then we don't have to do any of this stuff
on a per element basis.
* Print a warning in fiber for lacking render method
* Reject initial non-object state in Fiber
Rejects Arrays, Strings & Numbers. Allows nulls.
* Centralize fiber checks on ES6 Classes
* Add classic & instance property checks on fiber
- check the absence of getInitialState & getDefaultProps as methods
- check the absence of propTypes & contextTypes at instance-level
* Convert to normalized React `warning` calls
* Support lifecycle typo detection in fiber
* Get the complete warnings from the existing code
* Only check classInstance once
Avoid rechecking while resuming
* Can warn component while resuming but only once
This is achieved by tracking the warning state in the Fiber structure.
* Remove warning deduplication
* Factor name retrieval in a getName helper
* Use invariant instead of throw
* Read inst.state only once for the invariant
* Fix condition on the instance state
* Register failing/passing fiber tests
* Refactor scheduling functions and introduce Task priority
There was lots of duplication across all the scheduling functions. I
think we're far enough along that we can start trying to clean some
stuff up.
Also introduces a new priority level provisionally called Task priority.
This is for work that completes at the end of the current tick, after
the current batch of work has been committed. It's different from
Synchronous priority, which needs to complete immediately.
A full implementation of Task priority will follow. It will replace
the current batching solution.
* Implement Task priority
Task priority is similar to Synchronous priority. Both are flushed in
the current tick. Synchronous priority is flushed immediately (e.g. sync
work triggered by setState will flush before setState exits), where as
Task is flushed after the current batch of work is committed.
Currently used for batchedUpdates and nested sync updates. Task should
also be used for componentDidUpdate/Mount and error boundary work. I'll
add this in a later commit.
* Make error boundaries use Task Priority
I have all but one error fixed. Not sure how tricky the last one is,
but I'm cautiously optimistic. Pushing to show my current progress.
* Remove recursion from handleErrors
Changed the algorithm of handleErrors a bit to ensure that boundaries
are not revisited once they are acknowledged.
* Add incremental error boundary test
Discovered an edge case: a noop error boundary will break in incremental
mode unless you explicitly schedule an update.
* Refactor error boundaries in Fiber
* Simplify trapError() calls
The existing logic was written before we had a proper error handling system.
* Remove unnecessary flags
* Prevent performTaskWork recursion
* Be stricter about preventing recursion
Before, this code was bailing out after encoutering a null child because it thought it was out of old children. Seen when reconciling [null, <span />, <Image />] with [null, <span />, <Image />] in XUISelector.
Instead of scheduling individual callbacks to asap, we schedule one and
then do all the work in that one.
I'm doing this for architectural refactoring reasons.
Nevertheless, I'm adding a contrived unit test that this fixes. :)
* Make test more complete
* Add a failing test for scheduling in reverse order
It hangs forever because we don't clear next pointer when unscheduling a root. Therefore, when it's scheduled again, it brings all its previous chain with it, potentially creating a cycle.
* Clear the next pointer when unscheduling a root
Fixes a potential infinite cycle when we reschedule a root.
* Add new tests to Fiber test tracker