Czy React ponownie renderuje wszystkie komponenty i komponenty podrzędne przy każdym setState
wywołaniu?
Jeśli tak, to dlaczego? Pomyślałem, że pomysł polegał na tym, że React renderował tak mało, jak to konieczne - gdy stan się zmienia.
W poniższym prostym przykładzie obie klasy są renderowane ponownie po kliknięciu tekstu, pomimo faktu, że stan nie zmienia się przy kolejnych kliknięciach, ponieważ program obsługi onClick zawsze ustawia state
tę samą wartość:
this.setState({'test':'me'});
Spodziewałbym się, że renderowanie nastąpi tylko w przypadku zmiany state
danych.
Oto kod przykładu, jako skrzypce JS i osadzony fragment:
var TimeInChild = React.createClass({
render: function() {
var t = new Date().getTime();
return (
<p>Time in child:{t}</p>
);
}
});
var Main = React.createClass({
onTest: function() {
this.setState({'test':'me'});
},
render: function() {
var currentTime = new Date().getTime();
return (
<div onClick={this.onTest}>
<p>Time in main:{currentTime}</p>
<p>Click me to update time</p>
<TimeInChild/>
</div>
);
}
});
ReactDOM.render(<Main/>, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js"></script>
[1]: http://jsfiddle.net/fp2tncmb/2/
javascript
reactjs
Brad Parks
źródło
źródło
setState()
nawet z fałszywymi danymi powoduje, że element renderuje się inaczej, więc powiedziałbym „tak”. Absolutnie powinien spróbować ponownie renderować obiekt, gdy coś mogło się zmienić, ponieważ w przeciwnym razie demo - zakładając, że było to zamierzone zachowanie - nie działałoby!shouldComponentUpdate
metody, która, jak zakładam , musi być zawarta w React. Wygląda na to, że domyślna wersja zawarta w React po prostu zwracatrue
- co zmusza komponent do ponownego renderowania za każdym razem.Odpowiedzi:
Domyślnie - tak.
Istnieje metoda boolean powinnaComponentUpdate (obiekt nextProps, obiekt nextState) , każdy składnik ma tę metodę i jest odpowiedzialny za określenie „czy aktualizacja składnika (uruchomienie funkcji renderowania )?” za każdym razem, gdy zmieniasz stan lub przekazujesz nowe rekwizyty ze składnika nadrzędnego.
Możesz napisać własną implementację metody shouldComponentUpdate dla swojego komponentu, ale domyślna implementacja zawsze zwraca true - co oznacza, że zawsze uruchom ponownie funkcję renderowania.
Cytat z oficjalnych dokumentów http://facebook.github.io/react/docs/component-specs.html#updating-shouldcomponentupdate
Następna część twojego pytania:
Istnieją dwa kroki, które możemy nazwać „renderowaniem”:
Renderowanie wirtualnych DOM: po wywołaniu metody renderowania zwraca nową strukturę wirtualnych domen komponentu. Jak już wspomniałem wcześniej, ta metoda renderowania jest wywoływana zawsze podczas wywoływania metody setState () , ponieważ powinna domyślnie zwracać wartość true dla parametru trueComponentUpdate . Tak więc domyślnie w React nie ma optymalizacji.
Natywne rendery DOM: React zmienia rzeczywiste węzły DOM w przeglądarce tylko wtedy, gdy zostały zmienione w Virtual DOM i tak mało, jak to konieczne - jest to świetna funkcja React, która optymalizuje prawdziwą mutację DOM i sprawia, że React jest szybki.
źródło
setState
wtedy, gdy wykryjesz różnicę? Jeśli tak, jak to zrobić najlepiej - porównać ciągi JSON, skonstruować i porównać skróty obiektów ...?Nie, React nie renderuje wszystkiego, gdy zmienia się stan.
Za każdym razem, gdy komponent jest brudny (jego stan się zmienia), ten komponent i jego elementy potomne są renderowane ponownie. W pewnym stopniu ma to na celu jak najmniejsze ponowne renderowanie. Jedynym momentem, w którym renderowanie nie jest wywoływane, jest przeniesienie gałęzi do innego katalogu głównego, gdzie teoretycznie nie musimy niczego renderować ponownie. W twoim przykładzie
TimeInChild
jest to element podrzędnyMain
, więc jest również renderowany ponownie, gdy stanMain
zmian.React nie porównuje danych o stanie. Kiedy
setState
jest wywoływane, oznacza komponent jako brudny (co oznacza, że należy go ponownie renderować). Ważną rzeczą do zapamiętania jest to, że chociażrender
wywoływana jest metoda komponentu, prawdziwy DOM jest aktualizowany tylko wtedy, gdy dane wyjściowe są inne niż bieżące drzewo DOM (inaczej różnicowanie między wirtualnym drzewem DOM a drzewem DOM dokumentu). W twoim przykładzie, mimo żestate
dane nie uległy zmianie, zmienił się czas ostatniej zmiany, dzięki czemu wirtualny DOM różni się od DOM dokumentu, dlatego też HTML jest aktualizowany.źródło
render()
metoda była „czysta” - niezależna od stanu zewnętrznego.some branch is moved to another root
? Co pan zadzwonićbranch
? Co pan zadzwonićroot
?what does it mean some branch is moved to another root? What do you call branch? What do you call root?
Chociaż jest to stwierdzone w wielu innych odpowiedziach tutaj, komponent powinien:
zaimplementuj,
shouldComponentUpdate
aby renderować tylko w przypadku zmiany stanu lub właściwościprzełącz się na rozszerzenie PureComponent , który już implementuje
shouldComponentUpdate
wewnętrznie metodę płytkich porównań.Oto przykład zastosowań
shouldComponentUpdate
, który działa tylko w tym prostym przypadku użycia i celach demonstracyjnych. Gdy jest to używane, komponent nie renderuje się ponownie przy każdym kliknięciu i jest renderowany przy pierwszym wyświetleniu, a po kliknięciu raz.źródło
Tak. Wywołuje metodę render () za każdym razem, gdy wywołujemy metodę setState, gdy „shouldComponentUpdate” zwraca wartość false.
źródło
Kolejnym powodem „zagubionej aktualizacji” może być następująca:
Jeśli to jest problem, U może uniknąć ustawienia stanu podczas aktualizacji, należy sprawdzić wartość parametru stanu w ten sposób
Innym rozwiązaniem jest dodanie zainicjowanej właściwości do stanu i skonfigurowanie jej po raz pierwszy (jeśli stan jest inicjowany na wartość inną niż null).
źródło
Nie wszystkie elementy.
state
w wyglądzie składowych jak źródło wodospadu stanu całego APP.Tak więc zmiana następuje z miejsca, w którym wywołano setState.
renders
Stamtąd zostaje wywołane drzewo . Jeśli użyłeś czystego komponentu,render
zostanie on pominięty.źródło