Open andreypopp opened 11 years ago
What if instead you injected custom components for React.DOM.html
, React.DOM.head
and React.DOM.body
that could do a limited set of custom actions? That is, you could have an implementation of React.DOM.head on the client that never re-renders directly, but looks at how its this.props.children
changes and does custom DOM operations in componentDidUpadte()
.
@petehunt I thought of this but rather then doing things in componentDidUpdate
I wanted to override updateComponent
.
But it turns out it's not that easy — if we are happen to reconcile composite components which have different constructors and have React.DOM.{html,head}
in this._renderedComponent
(or even deep down in the composition hierarchy) then the reconciliation procedure will just prune the old tree and replace it with new markup.
So I'm thinking of the following:
React.DOM.head
and React.DOM.html
components with custom updateComponent
behaviour which will update its DOM attributes if any and take care of updating its children, so React.DOM.html
will delegate updating <head>
to child of type React.DOM.head
if any and React.DOM.head
will take care of not pruning unmanaged elements (<script>
and <link>
I think) while reconciliation.@petehunt forget about all I said previously — I think it requires a lot of changes in React. I've "fixed" mutateHTMLNodeWithMarkup.js
— https://gist.github.com/andreypopp/7474901
Now it has mutateHEADNodeWithMarkup
which updates head
children without setting innerHTML
and also prevents re-appending same <link>
elements so they are not refetched and so there are no blinks in UI due to stylesheet update.
There's one problem — this all seems like a huuuge dirty hack... anyway, what do you think about this changeset?
Currently React blows away entire markup during reconciliation if prev and next components have different constructors. That's not good for components rendered directly into
<html>
element — for example if some stylesheets were removed and then appended during reconciliation — page would blink.In
react-app
I solve this by declaring that pages are not components but specifications which are mounted into a single long-livedPage
component which is responsible to delegaterender()
and other lifecycle calls to such specifications.The requirement for such page specification is to always return
<html>
markup from arender()
call.This works well but creates an indirection layer where top-level components are not components but pages. I'd rather like them to be the same so I was wondering if it's possible to add a special code-path to react reconciliation mechanism for handling
<html>
element re-renders.