Usando plugin JQuery che trasformano il DOM in React Components?

Alcuni plugin JQuery non aggiungono semplicemente un comportamento ai nodes DOM, ma li cambiano. Ad esempio, Switch Bootstrap si trasforma

in qualcosa di simile

 
ON OFF

con

$("[name='my-checkbox']").bootstrapSwitch();

Quale non jive con React:

 Uncaught Error: Invariant Violation: findComponentRoot(..., .0): Unable to find element. This probably means the DOM was unexpectedly mutated (eg, by the browser), usually due to forgetting a  when using tables or nesting 

or tags. ......`.

Esiste una tecnica consigliata per incorporare questi plugin nei componenti React? O fondamentalmente rompono le ipotesi di React e non possono lavorare con esso?

No, reactjs reagirà (haha) male a qualsiasi cosa che modifichi la propria struttura dom del componente al di fuori di reactjs. Questo è qualcosa che non vorresti mai fare. La soluzione consigliata sarebbe replicare la funzionalità di qualsiasi cosa tu stia cercando di fare con un jquery o un plugin simile, in risposta.

Detto questo, c’è un modo ragionevole per farlo in casi specifici in cui non si può fare a meno di esso, ma in sostanza significa avvolgere alcune dom non reagenti all’interno di reactjs.

Esempio:

 var Example = React.createClass({ componentDidMount: function() { var $checkboxContainer = $(this.refs.checkboxContainer.getDOMNode()); var $checkbox = $('').prop('type', 'checkbox'); $checkboxContainer.append($checkbox); $checkbox.bootstrapSwitch({}); }, render: function() { return ( 
) } });

Ora ovviamente stai rendendo un componente con un div nidificato. Il nidificato quando viene montato su dom per la prima volta che div annidato riceverà una casella di controllo aggiunta da jquery, che eseguirà anche il nostro plug-in jquery su di esso.

Questo particolare componente di esempio non ha molto senso, tuttavia puoi vedere come questo potrebbe integrarsi in un componente più complesso pur consentendo di ri-renderlo e reactjs alle modifiche dello stato, ecc. Perdi la possibilità di reactjs direttamente agli eventi / modificare le cose all’interno della casella di controllo in questione che, per quanto riguarda la reazione, non esiste.

Ora, con l’esempio precedente, se dovessi avere qualche logica di reazione per aggiungere / rimuovere il div nidificato, dovresti avere la stessa logica intorno a quel div inserito per essere responsabile di reinserire la casella di controllo e reinizializzarla con il plugin jquery. Tuttavia, poiché reagisce solo modificando la dom quando necessario, questo contenuto dom inserito non verrà rimosso a meno che non si faccia qualcosa che modifichi il contenitore div in un modo che ne causa la rimozione / ripetizione alla dom. Ciò significa che puoi ancora accedere a tutti gli eventi in risposta per quel div contenitore ecc.

È anche ansible utilizzare la funzione componentDidMount per reactjs per associare eventi o callback a interazioni specifiche sulla casella di controllo stessa. Assicurati semplicemente di separarli correttamente in componentWillUnmount o ovunque abbia senso farlo nel ciclo di vita del componente nel tuo caso specifico.

In questo fantastico tutorial di ryanflorence avrai un’idea su come fare questo:

Disporre di dom Libs

Metodologia

  1. Le librerie DOM di solito manipolano il DOM
  2. React prova a ri-render e trova un DOM diverso da quello che ha avuto l’ultima volta e impazzisce
  3. Nascondiamo la manipolazione del DOM da React rompendo l’albero di rendering e quindi ricollegando il DOM manipolato dalla lib.
  4. I consumatori del nostro componente possono rimanere in React-land.

Certo, c’è una tale tecnica. Stiamo facendo queste cose tutto il tempo.

  1. Crei il componente React per avvolgere il plugin jQuery.
  2. All’interno del tuo render() , si restituisce un vuoto

  3. Nel tuo metodo componentDidMount, recuperi questo elemento con il suo riferimento e inizializza il tuo plugin jQuery lì.
  4. Nel componentWillUnmount , lo pulisci. Chiamando “distruggi” o qualsiasi altra cosa necessaria per evitare perdite di memoria.

Questo è tutto. Fortunatamente, è completamente sicuro modificare DOM in questo modo in React.

Se vuoi che questo plugin reagisca alle modifiche degli oggetti di scena, le cose diventano un po ‘più complicate. È necessario sovrascrivere altri metodi del ciclo di vita, come componentWillReceiveProps , controllare ogni volta che gli oggetti di scena sono effettivamente cambiati e chiamare i corrispondenti metodi di plugin. Posso spiegare in maggiore dettaglio, se avrai domande specifiche, l’argomento generale è troppo ampio per il commento.

Questa è più una questione filosofica

React è stato creato per ottimizzare le manipolazioni del DOM e ha un sacco di collegamenti dietro le quinte per farlo quando lo stato di un componente cambia tramite setState

Fare così farà sì che detto cablaggio attraversi il suo DOM virtuale per trovare i nodes che devono essere aggiornati

Se devi usare React, se vuoi provare a mantenere un livello di coerenza nella tua codifica, la soluzione migliore è applicare la manipolazione JQuery DOM all’interno del componenteDidMount in questo modo …

  componentDidMount(){ this.node = $("#"+this.props.id); // Keep a reference to the node this.chart = this.node.easyPieChart(); // Apply JQuery transformation and keep a reference this.percentTitle = this.chart.find(".percent"); // Keep a reference to the title } 

Fatto ciò, qualunque sia il metodo di “aggiornamento”, NON effettuare alcuna chiamata a setState, invece, chiamare qualsiasi metodo di aggiornamento che potrebbe avere il componente JQuery, in questo modo …

  componentWillMount(){ this.interval = setInterval(this._doRefresh.bind(this), 1500); } _doRefresh( percentage ){ // Note how setState is NOT being called here percentage = percentage || Math.floor (Math.random() * 100) // simulate since we're not getting it yet this.chart.data('easyPieChart').update(percentage); // call easyPieChart's update this.percentTitle.text(percentage); } 

A questo punto, se ti stai chiedendo perché utilizzare React, beh, nel mio caso, questo componente è un elemento in un elenco di altri componenti di React ed è stato usato per mantenere la coerenza in tutta l’applicazione … Potresti avere un simile dilemma

Se, diversamente da me, sei abbastanza sfortunato che il tuo componente non ha un metodo di aggiornamento, e non puoi crearne uno, potrebbe essere il momento di ripensare completamente l’approccio