2016-03-17 32 views
12

Questo è un problema ricorrente che ho con React. Si garantisce che il metodo componentDidMount venga attivato quando il componente viene sottoposto a rendering per la prima volta, quindi sembra un luogo naturale per prendere misure DOM come altezze e offset. Tuttavia, molte volte ricevo letture di stile errate a questo punto del ciclo di vita del componente. Il componente è nel DOM, quando si interrompe con il debugger, ma non è ancora stato dipinto sullo schermo. Ottengo questo problema con elementi che hanno larghezza/altezza per lo più al 100%. Quando eseguo le misurazioni in componentDidUpdate - tutto funziona correttamente, ma questo metodo non verrà attivato al rendering iniziale del componente.Quando viene eseguito esattamente `componentDidMount`?

Quindi la mia domanda è - quando è esattamente componentDidMount sparato perché ovviamente non viene attivato dopo che tutte le vernici del browser sono state fatte.

EDIT: offerte This Stackoverflow issue con lo stesso soggetto:

Si fa inoltre riferimento this github conversation che spiega cosa succede

+0

Questo sembra rilevante: http://stackoverflow.com/questions/25371926/using-react-how-can-i-get-the-width-of-an-auto-sized-dom -elemento – lux

risposta

12

All'interno di un albero componente reattivo, componentDidMount() viene generato dopo che sono stati montati anche tutti i componenti figlio. Ciò significa che il componente componentDidMount() di un componente viene attivato prima che il suo genitore sia stato montato.

Quindi, se si desidera misurare la posizione e le dimensioni del DOM ecc., Utilizzare componentDidMount() di un componente figlio è un luogo/tempo non sicuro per farlo.

Nel tuo caso: per ottenere la lettura accurata al 100% da componenti larghezza/altezza, un luogo sicuro per prendere tali misure sarebbe all'interno del componentDidMount() del superiore reagiscono componente.
100% è una larghezza/altezza relativa al genitore/contenitore.Quindi le misurazioni possono essere eseguite solo dopo aver montato anche il genitore.

+0

Questo sembra rispondere alla mia domanda! Tuttavia, sono un po 'confuso su come 'componentDidMount' essere licenziato prima che il contenitore genitore sia montato. Se non ci sono elementi DOM che rappresentano il genitore, dov'è l'elemento del componente inserito nel DOM? – disc0dancer

+0

Alcune ricerche in giro non forniscono risposte ovvie a questo mistero, temo. Probabilmente a causa di reagire sotto i meccanismi del cappuccio. La mia ipotesi è che l'elemento genitore si trovi già nel DOM, ma che la formattazione è garantita solo quando 'componentenDidMount()' viene attivato all'interno del componente principale. – wintvelt

2

Come forse sapete, componentDidMount viene attivato solo una volta subito dopo la resa iniziale.

Poiché si stanno effettuando misurazioni, sembrerebbe che si desideri attivare anche la misurazione quando componentDidUpdate nel caso in cui le misurazioni cambino quando si aggiorna il componente.

Si noti che componentDidUpdate non si verifica per il rendering iniziale, quindi è probabile che sia necessario che entrambi gli eventi del ciclo di vita attivino la gestione delle misurazioni. Verifica se questo secondo evento si innesca per te e se ha misurazioni diverse.

Secondo la mia opinione, si dovrebbe evitare di usare setTimeout o requestAnimationFrame quando possibile.

React Lifecycle Reference.

0

è possibile provare la logica di ritardo in componentDidMount() con requestAnimationFrame(). la logica dovrebbe essere dopo la prossima verniciatura.

tuttavia, avremmo bisogno di sapere di più sul tuo codice per capire perché i nodi non sono stati dipinti. non ho mai avuto questo problema componentDidMount() si attiva subito dopo l'aggiunta dei dom node alla pagina, ma non necessariamente dopo la loro colorazione.

0

Se si desidera rispondere a qualcosa che viene montato nel DOM, il modo più affidabile per farlo è con un ref callback. Per esempio:

render() { 
    return (
    <div 
     ref={(el) => { 
     if (el) { 
      // el is the <div> in the DOM. Do your calculations here! 
     } 
     }} 
    ></div> 
); 
} 
Problemi correlati