2014-10-20 11 views
6

Quindi ho una semplice app React/Flux che utilizza il router di Backbone. Ho un caso in cui l'utente crea un oggetto e il percorso si aggiorna da /object/new a /object/:id. Tuttavia, non è necessario eseguire nuovamente il rendering della pagina, poiché il componente è lo stesso e, a causa dell'aggiornamento del negozio associato dopo il ritorno della chiamata ajax-crea, si aggiorna automaticamente.React way to route senza re-rendering

Attualmente, ho appena applicato una patch al router per esporre un metodo che aggiorna solo l'url e che in realtà non ha colpito il metodo specifico del percorso. Questo sembra hacky, e in realtà non affronta i casi in cui alcuni componenti (cioè un widget) devono essere aggiunti/rimossi (almeno rimuove la responsabilità di sapere quali componenti devono essere resi dal router), ma il primario L'interfaccia utente non ha bisogno di essere ricreata.

Quindi questo mi lascia con tre domande:

  1. Qual è il modo agire per gestire i cambiamenti di URL che non richiedono componenti che cambiano?
  2. E le modifiche dell'URL che aggiungono/modificano determinati componenti?
  3. I negozi dovrebbero essere responsabili dell'avvio di eventi di instradamento?

risposta

10

Una delle principali proposizioni di valore di React è che il re-rendering è molto molto economico.

Ciò significa che è possibile eseguire il rerender in modo eccessivo senza effetti negativi. Questo è un 180 completo da Backbone, dove il rendering è molto costoso, il che porta alla logica che stai cercando, ovvero come evitare i rendering.

Sotto il cofano, React esegue questo controllo differenziando il DOM virtuale con il DOM. In altre parole: quando si utilizza la funzione di rendering esposta in React, non si esegue il rendering del DOM, piuttosto si descrive semplicemente il nuovo stato del DOM con Javascript.

In pratica, ciò significa che se non si calcolano molti valori, è possibile eseguire nuovamente il rerender a 60 fotogrammi al secondo senza alcuna procedura di ottimizzazione.

Questo ti dà la libertà di "re-rendering" completamente, anche se solo poche cose sulla tua app in realtà cambiano.

Quindi il mio consiglio è di non provare effettivamente nulla per impedire a React di eseguire il rerender dell'intera pagina, anche se non cambia nulla. Questo tipo di logica aggiungerà complessità, ed è possibile evitare questa complessità senza alcun costo riorganizzando incondizionatamente il cambiamento di rotta. Ciò ha senso anche da un punto di vista concettuale, dal momento che il percorso non è altro che lo stato di app globale.

La libertà di poterlo fare è uno dei motivi principali per cui React è fantastico.

Si tratta di un caso classico di "ottimizzazione prematura è la radice di tutti i mali".

Ad esempio: a volte, a livello globale, rieseguo l'intera gerarchia DOM su eventi mouseMove e non si osservano impatti sulle prestazioni.

Come regola generale, si consideri un rerender come un'operazione a costo zero. Ora potresti avere alcune operazioni costose nei componenti React in corso. In tal caso, è possibile utilizzare i metodi del ciclo di vita di React per eseguirli su richiesta.Soprattutto dare un'occhiata a shouldComponentUpdate, componentWillReceiveProps e componentWillUpdate.

Se si utilizza Flux e si aderisce al paradigma dell'immutabilità, è possibile effettuare controlli di uguaglianza referenziati di stato e oggetti di scena per fare lavori su richiesta. Con questo, puoi migliorare le prestazioni.

Con il metodo shouldComponentUpdate, è possibile impedire una chiamata di rendering se richiede troppa potenza di calcolo. Tuttavia, lo farei solo se produce prestazioni migliorate a causa di un'operazione costosa da te implementata.

Nel tuo caso, vorrei iniettare lo stato del percorso nel componente root, iniettarli come oggetti di scena nei figli della radice e implementare shouldComponentUpdate su di essi per impedire un rendering.

+0

Risposta straordinaria: grazie per aver dedicato del tempo! – mattmattmatt