React.render reloads iframes when rendering with a new component
See original GitHub issueI’ve run into this issue when integrating live reloading into our toolchain. Example is obviously convoluted as it tries to capture our setup and also illustrate the issue. The problem is once we swap modules we end up with a new sets of react component definitions and even though their keys and render output is equal iframe still seem to get reloaded.
var Thunk = function(props, context) {
React.Component.call(this, props, context);
}
Thunk.for = function(view, key) {
var ReactComponent = function(props, context) {
Thunk.call(this, props, context)
}
ReactComponent.prototype = Object.create(Thunk.prototype);
ReactComponent.displayName = key.split('@')[0];
return ReactComponent
}
Thunk.prototype = Object.create(React.Component.prototype);
Thunk.prototype.shouldComponentUpdate = function(props) {
this.props.model !== props.model
}
Thunk.prototype.render = function() {
return this.props.view(this.props.model)
}
let render = (key, view, model) => {
let component = view.reactComponent ||
(view.reactComponent = Thunk.for(view, key));
return React.createElement(component, {key, view, model});
}
let redFrame = ({src}) => React.DOM.iframe({
key: 'frame',
style: {border: '1px solid red'},
src
})
let blueFrame = ({src}) => React.DOM.iframe({
key: 'frame',
style: {border: '1px solid blue'},
src
})
React.render(render('main', redFrame, {src: 'https://facebook.github.io/react/docs/getting-started.html'}), document.body)
setTimeout(function() {
React.render(render('main', blueFrame, {src: 'https://facebook.github.io/react/docs/getting-started.html'}), document.body)
}, 3000);
P.S. I also tried to keep the same root component to keep the identical data-reactid
attributes across React.render
calls but iframes still reload.
Edit: Updated example so view
from props is used and note stored as property of the class which seemed to cause confusion
Issue Analytics
- State:
- Created 8 years ago
- Comments:7
Top Results From Across the Web
How do you reload an iframe with ReactJS? - Stack Overflow
You could create a new component which just loads you iframe. In your main component you load it and give it a update...
Read more >Forcing an iframe to rerender with React - neemzy
If that happens, chances are you might want to force it to refresh based on some change in the overlying component, that is...
Read more >Rendering in an iframe in a React app - DEV Community
Sometimes you want to render a tree of components within an iframe . You may want to do this because you may be...
Read more >Best practices for React iframes - LogRocket Blog
Let's get started! Best practices for using iframes in React. When a resource is rendered in an iframe, it functions independently of the...
Read more >Handling iframe loading in React - Medium
We'll set a ternary that loads the spinner while the iframe is loading. class Rsvp extends React.Component { constructor(props) {
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Two things determine whether a component is reused: the type and the key. If either changes, the component is unmounted and remounted. See:
https://github.com/facebook/react/blob/3dbdb63a7dbdf31522a623bd627a64c230cdfdcf/src/renderers/shared/reconciler/shouldUpdateReactComponent.js
Since your
view.reactComponent
value is different in the two cases, the component gets remounted.That being said this did not fully covered my use case as while our primarily is using
render
(similar to one in the example) there are still handful of plain react components to workaround few other limitations. For that I basically end up wrappingReact.createElement
andReact.findDOMNode
in order to always use sameProxy
component to which I pass actual component type as prop. I’m little worried about the robustness of this solution so I’d welcome any comments if @spicyj or @petehunt will have few moments to spare to look at it:https://github.com/Gozala/browser.html/commit/731e48e8a2d10a02bcca2281e6cc06f9b7201186