ReactJS-czy render jest wywoływany po wywołaniu "setState"?

Czy React ponownie renderuje wszystkie komponenty i podzespoły przy każdym wywołaniu setState?

Jeśli tak, to dlaczego? Myślałem, że chodzi o to, że React renderuje tylko tak mało, jak to konieczne - kiedy stan się zmienił.

W poniższym prostym przykładzie obie klasy renderują się ponownie po kliknięciu tekstu, pomimo faktu, że stan nie zmienia się przy kolejnych kliknięciach, ponieważ obsługa onClick zawsze ustawia state na tę samą wartość:

this.setState({'test':'me'});

Spodziewałem się, że rendery będą tylko dzieje się, jeśli state dane uległy zmianie.

Oto kod przykładu, jako 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/
Author: Brad Parks, 2014-07-13

2 answers

Czy React ponownie renderuje wszystkie komponenty i podzespoły przy każdym wywołaniu setState?

Domyślnie-tak.

Istnieje metoda boolean shouldComponentUpdate (object nextProps, object nextState) , każdy komponent ma tę metodę i jest odpowiedzialny za określenie " shouldcomponent update (run render function)?"za każdym razem, gdy zmieniasz Stan lub przekazujesz nowe Właściwości z komponentu nadrzędnego.

Możesz napisać swój własny implementacja metody shouldComponentUpdate dla Twojego komponentu, ale domyślna implementacja zawsze zwraca true-co oznacza, że zawsze uruchamia ponownie funkcję renderowania.

Cytat z oficjalnych dokumentów http://facebook.github.io/react/docs/component-specs.html#updating-shouldcomponentupdate

Domyślnie shouldComponentUpdate zawsze zwraca true, aby zapobiec subtelne błędy, gdy stan jest zmutowany na miejscu, ale jeśli jesteś ostrożny, aby zawsze traktuj stan jako niezmienny i do odczytu tylko z właściwości i stanu w render() wtedy możesz nadpisać shouldComponentUpdate za pomocą implementacji, która porównuje stare rekwizyty i stan do ich zastępstwa.

Następna część twojego pytania:

Jeśli tak, to dlaczego? Myślałem, że chodzi o to, że React renderuje tylko tak mało, jak to konieczne - kiedy stan się zmienił.

Istnieją dwa kroki tego, co możemy nazwać "renderowaniem":

  1. Virtual DOM render: gdy wywołana jest metoda render zwraca nową strukturę Wirtualnego dom komponentu. Jak wspomniałem wcześniej, ta metoda render jest wywoływana zawsze, gdy wywołujesz setState () , ponieważ shouldComponentUpdate zawsze domyślnie zwraca true. Tak więc domyślnie w Reaccie nie ma optymalizacji.

  2. Natywne renderowanie DOM: React zmienia rzeczywiste węzły DOM w przeglądarce tylko wtedy, gdy zostały zmienione w wirtualnym DOM i tak mało, jak to konieczne - to jest ta świetna funkcja Reacta co optymalizuje rzeczywistą mutację DOM i sprawia, że reagują szybko.

 381
Author: Petr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-06 16:16:35

Nie, React nie renderuje wszystkiego po zmianie stanu.

  • Za każdym razem, gdy komponent jest brudny (zmienia się jego stan), komponent i jego dzieci są ponownie renderowane. To, do pewnego stopnia, ma na celu odtworzenie jak najmniej. Jedynym momentem, kiedy render nie jest wywoływany jest przeniesienie jakiejś gałęzi do innego roota, gdzie teoretycznie nie musimy niczego ponownie renderować. W twoim przykładzie, TimeInChild jest elementem potomnym Main, więc jest również renderowany ponownie, gdy stan Main zmiany.

  • React nie porównuje danych stanu. Kiedy setState jest wywołana, oznacza komponent jako brudny (co oznacza, że musi zostać ponownie wyrenderowany). Należy zauważyć, że chociaż wywołana jest metoda render komponentu, rzeczywisty DOM jest aktualizowany tylko wtedy, gdy wyjście różni się od bieżącego drzewa DOM (a. K. różni się między wirtualnym drzewem DOM a drzewem Dom dokumentu). W twoim przykładzie, mimo że dane state się nie zmieniły, czas ostatniej zmiany się zmienił, co Wirtualny DOM różni się od Dom dokumentu, dlatego HTML jest aktualizowany.

 71
Author: tungd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-24 15:25:44