C'è un modo per mantenere l'istanza iframe in qualche archivio globale e solo montarlo sul DOM quando necessario?
sì, si potrebbe, ma se si rimuove anche un iframe dal DOM e ri-aggiungere in un secondo momento viene comunque ricaricato, così in questo modo il problema in realtà ha ben poco a che fare con del Reagire albero componente. Quello di cui hai veramente bisogno è semplicemente nascondere iframe e mostrarlo di nuovo più tardi.
Si potrebbe naturalmente nascondere e mostrare l'iframe in Reagire in questo modo:
{ <iframe src="..." style={{display: this.state.showing ? "block" : "none"}} /> }
In questo caso è necessario per rendere l'iframe in qualche luogo che non venga smontato. È possibile utilizzare i componenti più in basso nell'albero per comunicare nuovamente verso l'alto per mostrare/nascondere l'iframe.
Ma se si vuole davvero essere in grado di nascondere/mostrare l'iframe da diversi posti nel vostro albero componente che vengono montati e smontati, è possibile, ma diventa un po 'più complicato e non un tipico caso d'uso di React.
Avrete bisogno di creare il iframe DOM da soli e aggiungerlo da qualche parte nel DOM che si trova all'esterno dell'albero dei componenti di React (questo è generalmente un anti-pattern in React). Quindi puoi usare un componente proxy per mostrare/nascondere questo elemento DOM quando montato e smontato.
Ecco un esempio che aggiunge un iframe per la document.body
e lo mostra quando un componente è montato, e lo nasconde quando il componente è smontato:
class WebView extends React.Component {
static views = {};
componentDidMount() {
if (!WebView.views[this.props.url]) {
WebView.views[this.props.url] = this.createWebView(this.props.url);
}
WebView.views[this.props.url].style.display = "block";
}
componentWillUnmount() {
WebView.views[this.props.url].style.display = "none";
}
createWebView(url) {
let view = document.createElement("iframe");
view.src = this.props.url;
document.body.appendChild(view);
return view;
}
render() {
return null;
}
}
Here it is working on CodePen: notare che quando si nasconde (smontare) e poi mostra (monta) lo WebView
lo stato iframe (ad esempio l'input di ricerca) rimane lo stesso.
Sarà inoltre necessario posizionare e dimensionare l'iframe per visualizzarlo correttamente nel layout. Non l'ho mostrato perché è un po 'difficile da risolvere in generale.
Si noti che questa soluzione è simile a "portal" pattern. La differenza qui è non smontare mai l'iframe per preservare il suo stato e impedire il ricaricamento.