New module! With this, we have a new module that uses the component tree to store DOM nodes. Most of the logic in this file relates to markup adoption -- if we were to drop that (along with server rendering) this file could just be a `return inst._nativeNode;`.
This works with useCreateElement only because we need to reference each node as it's created.
Events is now the only thing using ReactMount.getNode -- I'll introduce pointers back from the DOM nodes (and a `ReactDOMComponentTree.getInstanceFromNode`) and make that work.
Is this all of them? I hope so.
- Set text content after creating hierarchy, like the text is a child. I should've done this originally but I guessed it wouldn't matter. I was wrong (~20% perf difference in IE11).
- IE throws when setting an enum-like property to an invalid value. I tried setting every property to the string 'a' and changed the ones that threw to be MUST_USE_ATTRIBUTE. I think these are all correct -- encType is the most suspicious one based on the existing comments but I tested in IE8 and it works fine as an attribute.
My last strategy of getting each node recursively while unmounting was a pain to make work properly with ReactMount's confusing cache. Now, we get the node before unmounting anything in the subtree (and we don't try to find the nodes of descendants).
This is a temporary solution and can go away when we get rid of the giant ReactMount node hash map.
Fixes#5151.
Now we don't repurpose context for our own secret needs (hi Dan). In this diff I avoid storing the native parent on native (DOM) components and store it only on composites, but we'll probably want to store it on native components too soon for event bubbling.
This is probably slightly slower for unmounts in the case that no updates were ever performed, but caching the node on the instance should make updates faster. In any case, the more important consequence of this change is that we can fix the current memory leak that happens when swapping composite types.
Behind a feature flag. This is a relatively simple change; adopting this strategy universally would mean that we could clean up a lot of code but this doesn't attempt to restructure more than necessary.
This is a machine-generated codemod, but it's pretty safe since it was
generated by hooking into eslint's own report.
A few files had to be touched up by hand because there were existing
formatting issues with nested arrays/objects:
src/shared/utils/__tests__/OrderedMap-test.js
src/shared/utils/__tests__/Transaction-test.js
src/shared/utils/__tests__/traverseAllChildren-test.js
src/isomorphic/children/__tests__/ReactChildren-test.js
The new folder structure is organized around major packages that are expected to ship separately in some form.
`/isomorphic`
I moved classic/modern and children utils into a directory called "isomorphic" with the main export being ReactIsomorphic. This will eventually become the "react" package.
This includes all the dependencies that you might need to create a component without dependencies on the renderer/reconciler.
The rest moves into decoupled renderers.
`/renderers/dom/client` - This is the main renderer for DOM.
`/renderers/dom/server` - This is the server-side renderer for HTML strings.
`/addons` and `/test` - Same as before for now.
You're not supposed to take on a dependency inside another package.
Shared code is organized into a "shared" directory which is intended to support all the packages in that subdirectory. Meaning that once we swap to CommonJS modules, the only time you should use `..` is to target `../shared/` or `../../shared`.
E.g. `/shared/` is common utils that are used by everything.
`/renderers/shared/` is code that is shared by all renderers, such as the main reconciliation algorithm.
Shared code will likely be copied into each package rather than referenced. This allow us to have separate state and allow inlining and deadcode elimination.