2016-07-04 18 views
5

In un progetto basato su React + Redux, ho un componente edi connect() che controlla le autorizzazioni dell'utente tramite un recupero API. Le autorizzazioni recuperate sono memorizzate nell'archivio di Redux.Re-rendering del componente connect() ed in base all'output mapStateToProps

Il componente è fondamentalmente simile a <Can check="...">...</Can>, che comunica con la nostra API (tramite azioni di Redux) per risolvere il controllo. Se viene concessa l'autorizzazione, viene eseguito il rendering this.props.children, null in caso contrario.

Per questo, mapStateToProps() calcola un puntello passes da dati di autorizzazione nell'archivio, che è selezionato nel metodo <Can /> s render(). Io uso il parametro ownProps su mapStateToProps() per ottenere il "materiale da controllare" e calcolare il flag passes.

C'è un po 'di memorizzazione nella cache, quindi non riesco a recuperare su ogni mount del componente, e funziona fondamentalmente. A volte, tuttavia, il componente non viene riprodotto nuovamente quando il puntello passes viene aggiornato a true (verrà comunque visualizzato dopo la navigazione - utilizzando il router di risposta - e di nuovo indietro, quindi in pratica se il componente viene reinstallato).

Do connect() i componenti ed eseguono nuovamente il rendering se l'uscita da mapStateToProps() cambia? La documentazione per s connect()react-redux' dire questo:

Se ownProps è specificato come secondo argomento, il suo valore sarà gli oggetti di scena passati al componente, e mapStateToProps sarà nuovamente invocato ogni volta che il componente riceve nuovi oggetti di scena.

Ciò significa che il passaggio in ownProps modifica il rendering in modo che venga eseguito nuovamente il rendering se gli oggetti di scena cambiano o in altro modo? Come posso capire la nota riguardante la memoizzazione/restituire una funzione da mapStateToProps(), o non è nemmeno correlata?

Grazie

risposta

8

COLLEGARE() componenti ED ri-renderizzare Se l'uscita dal mapStateToProps) variazioni (? I documenti per react-redux's connect() dicono questo:

L'uscita da una funzione non può cambiare da sola. In primo luogo, qualcosa deve attivare questa funzione per essere rivalutata.

Se lo stato di Redux cambia, mapStateToProps viene rivalutato.

Se puntelli ricevuti dal componente principale sono superficialmente disuguale (sono cambiati) e si utilizza ownProps argomento, mapStateToProps è anche rivalutati.

Se mapStateToProps ha restituito valori uguali all'ultima chiamata, React Redux salterà il rendering. Se restituisce valori non uguali in modo superficiale, il componente avvolto verrà nuovamente sottoposto a rendering. Si presume che lo stesso mapStateToProps sia una funzione pura.

A volte, però, il componente non ri-renderizzare quando i passi aggiornamenti puntello per vero

Si prega di creare un progetto minimal riprodurre questo e il file un problema con l'esempio relativo codice.

Come posso capire la nota relativa alla memoizzazione/alla restituzione di una funzione da mapStateToProps() o non è nemmeno correlata?

Non correlato.

+0

Grazie per aver risposto così in fretta. Controllerò di nuovo e assicurarmi che nulla nella logica del riduttore o del selettore sia effettivamente errato prima di presentare un problema. Il controllo poco accurato sull'uguaglianza potrebbe essere un problema. –

+0

Come suggerimento rapido per i documenti [connect()] (https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options), forse cambia il la formulazione di _ [...] e mapStateToProps verrà richiamata * in aggiunta * ogni volta che il componente riceve nuovi oggetti di scena. –

+0

Un PR è benvenuto! –

7

Molte cose da sapere qui:

  1. connect sarà poco profonde confrontare l'uscita dell'ultimo mapState chiamata al corrente mapState chiamata. Se nulla è cambiato, non verrà ricreato il componente spostato.
  2. Per impostazione predefinita, connect verrà eseguito solo mapState quando il negozio notifica gli abbonati. Tuttavia, se la tua funzione mapState viene dichiarata come presa due parametri, connect passerà nei puntelli del componente spostato come secondo argomento, consentendo di eseguire operazioni come state.somePerItemData[ownProps.itemId]. Chiama anche mapState in qualsiasi momento in cui gli oggetti di scena in arrivo differiscono, in quanto ciò potrebbe influire sull'output di mapState.
  3. La memoizzazione predefinita di Reselect mantiene solo un singolo valore memorizzato nella cache per funzione di selezione. Se si dispone di un componente che viene istanziato più volte e tutte le istanze condividono la stessa istanza della funzione di selezione, la memoizzazione del selettore probabilmente non funzionerà nel modo desiderato, poiché ogni istanza del componente probabilmente la chiama con input diversi (ad esempio i propri oggetti di scena). Pertanto, come ottimizzazione avanzata, è possibile passare una funzione di fabbrica come argomento mapState, che potrebbe creare un'istanza di funzione selettore univoca per ogni istanza del componente.

Detto questo, temo di non avere una risposta specifica per la tua domanda sul componente non aggiornato. Probabilmente avrei bisogno di vedere il codice in modo più dettagliato.

+0

Grazie per il chiarimento. Non usiamo Riseleziona, ma posso vedere il problema che descrivi. Mi mancava il fatto che l'uso di 'ownProps' in' mapState' causasse una nuova rivalutazione di 'mapState', non esclusiva. –