2016-05-18 17 views
5

Ho un modulo a più fasi e sto utilizzando react-router per navigare tra i diversi passaggi. In alcuni dei passaggi I mostra un iframe all'utente. Quando l'utente si sposta tra i passaggi sempre smontare e rimontare dall'iframe, questo provoca due problemi:Mantenere i componenti tra i percorsi utilizzando il router di risposta

  1. ricaricata dall'iframe dalla sorgente, che lo rende saltare.
  2. Poiché è un iframe, non posso controllare il suo stato interno e perde lo stato tra i passaggi. Quindi, se l'utente aveva alcuni input per l'iframe, quando si passa alla fase successiva gli input vengono persi.

C'è un modo per mantenere l'istanza di iframe in qualche archivio globale e solo montarlo sul DOM quando necessario?

Altre idee su come risolvere questo problema?

Grazie.

risposta

1

Molto semplicemente, non c'è modo di conservare un componente nell'albero di rendering se il genitore non è reso. Cioè, quando il percorso cambia, il tuo componente sarà necessariamente smontato se si tratta di un bambino su un Route.

Un modo per eseguire il passaggio laterale è quello di rendere il proprio componente non un bambino per nessuna rotta a tutti. In questo modo, è sempre rendere questo componente accanto a ogni percorso. Quindi puoi semplicemente usare gli stili per mostrarlo/nasconderlo quando appropriato. Ovviamente, ciò comprometterà in parte la struttura del tuo DOM.

4

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.

Problemi correlati