Strict Rejim

Applikasiyada potensial problemləri vurğulayan alətlərdən biri StrictMode-dur. StrictMode, Fragment kimi heç bir görünən UI render etmir. Bu alət sadəcə uşaqlar üçün əlavə yoxlamalar edərək xəbərdarlıqlar göstərir.

Qeyd:

Strict rejim yoxlamaları yalnız development zamanı olur. Bu rejim produksiya quruluşuna heç bir təsir etmir.

Strikt rejimi applikasiyanın istənilən hissəsində activləşdirmək mümkündür. Məsələn:

import React from 'react';

function ExampleApplication() {
  return (
    <div>
      <Header />
      <React.StrictMode>
        <div>
          <ComponentOne />
          <ComponentTwo />
        </div>
      </React.StrictMode>
      <Footer />
    </div>
  );
}

Yuxarıdakı nümunədə, strict rejim yoxlamaları HeaderFooter komponentlərində işlədilməyəcək. Lakin, ComponentOne, ComponentTwo və bu komponentlərin ağacında olan bütün komponentlərdə yoxlamalar aktivləşəcək.

StrictMode aşağıdakı problemlər üçün faydalıdır:

React-in gələcək buraxılışlarında bu moda yeni xüsusiyyətlər əlavə ediləcək.

Təhlükəli lifecycle funksiyalarının tapılması

Bu bloq yazısında göstərildiyi kimi, asinxron React applikasiyalarında bəzi lifecycle funksiyalarının işlədilməsi təhlükəlidir. Lakin, 3-cü tərəfinin kitabxanalarını işlətdikdə bu lifecycle-ların işlənmədiyindən əmin olmaq çətinləşir. Xoşbəxtlikdən, strict rejim sizə kömək edə bilər!

Strict rejim aktiv olduqda təhlükəli lifecycle funksiyaları işlədən klas komponentlərinin siyahısını yaradılır və bu komponentlər haqqında məlumatlar xəbərdarlıq kimi loq edilir:

strict mode unsafe lifecycles warning

Strict rejimdən yaranan problemləri indi həll etdikdə React-in gələcək buraxılışlarında asinxron render etmədən tam faydalana biləcəksiniz.

Köhnə mətn ref API-ının istifadə edilməsi haqqında xəbərdarlıq

Əvəllər, React-də ref-lərin iki növ istifadəsi var idi: köhnə mətn ref API-ı və callback API-ı ilə. Mətn ref-lərin işlədilməsinin daha asan olduğuna baxmayaraq bu ref-lərin bir neçə problemləri var. Bu səbəbdən, rəsmi tövsiyyəmiz callback ref-dən istifadə etmək idi.

React 16.3-də, mətn ref-lərinin asanlığı olan və heç bir problemini daşımayan yeni ref API-ı əlavə edildi:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);

    this.inputRef = React.createRef();
  }

  render() {
    return <input type="text" ref={this.inputRef} />;
  }

  componentDidMount() {
    this.inputRef.current.focus();
  }
}

Obyekt ref-ləri mətn ref-lərini əvəz etmək üçün əlavə edilib. Bu səbəbdən, mətn ref-ləri işləndiyi zaman strict rejim xəbərdarlıqlar göstərir.

Qeyd:

createRef API-ından əlavə, callback ref-lərindən də istifadə etmək mümkündür.

Komponentlərdə callback ref-lərini dəyişmək lazım deyil. Bu ref-lərin daha əyilən olduğundan bu ref-lərə genişləndirilmiş xüsusiyyət kimi baxılır.

createRef API-ı haqqında buradan məlumat ala bilərsiniz.

Köhnə findDOMNode-un istifadə edilməsi haqqında xəbərdarlıq

React-də klas instansiyası əsasında ağacda DOM nodunun tapılması üçün findDOMNode funksiyasından istifadə edilirdi. Normalda, ref-in DOM-a birbaşa qoşulması bu funksiyanın istifadəsini əvəzləyir.

findDOMNode funksiyası klas komponentləri ilə də işləyir. Lakin, bu xüsusiyyət valideynin xüsusi uşaqları render etməsinə imkan yaratdığından abstraksiya dərəcələrini sındıra bilir. Valideyn komponenti uşaq komponentin DOM noduna yönəltdiyindən refaktorinq üçün problemlər yaranır. findDOMNode funksiyası yalnız bir uşaq qaytara bilir. Lakin, Fraqmentlərdən istifadə edərək bir neçə DOM nodu render etmək mümkündür. findDOMNode bir dəfə oxumaq üçün yaranmış API-dır. Bu API, yalnız lazım olduqda cavab qaytarır. Uşaq komponent fərqli nod render etdikdə dəyişiklikləri idarə etmək mümkün deyil. Bu səbəbdən, findDOMNode funksiyası komponentlər, dəyişməyən tək DOM nod qaytardıqda işlədilirdi.

İndi, ref-i xüsusi komponentə göndərib komponentin DOM noduna yönləndirə bilərsiniz.

Əlavə olaraq, komponentdə əhatə olunan DOM nodu əlavə edib ref-i birbaşa bu noda qoşa bilərsiniz.

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.wrapper = React.createRef();
  }
  render() {
    return <div ref={this.wrapper}>{this.props.children}</div>;
  }
}

Qeyd:

DOM nodunun şablonun bir hissəsi olmaması üçün display: contents CSS atributundan istifadə edə bilərsiniz.

Gözlənilməz side effektlərin tapılması

Konseptual olaraq React iki fazadan ibarətdir:

  • render fazasında DOM-da baş verəcək (və ya nativ görünüşə) dəyişikliklər müəyyənləşdirilir. Bu faza zamanı, render funksiyası çağrılaraq cari nəticə əvvəlki render nəticəsi ilə müqayisə olunur.
  • commit fazasında lazımı dəyişikliklər tətbiq edilir. (Bu, React DOM-da DOM nodlarının əlavəsi, silinməsi, və ya yenilənməsi əməlliyatlarıdır.) Əlavə olaraq, bu fazadacomponentDidMountcomponentDidUpdate kimi lifecycle funksiyaları çağrılır.

Adətən, commit fazası tez, render fazası isə yavaş olur. Bu səbəbdən, gələcək asinxron modunda (standart aktiv olmayacaq) render işi bir neçə yerə bölünəcək. Brauzeri blok etməmək üçün işlər fasilə ilə icra olunacaqlar. Bu deməkdir ki, render fazası lifecycle-ları, commit fazasından öncə bir neçə dəfə çağrıla bilər. Bu lifecycle-lar commit fazası olmadan da çağrıla bilərlər (yüksək prioritet kəsilməsi zamanı və ya xətada nəticəsində).

Render fazasının lifecycle-ları aşağıda göstərilən klas metodlarıdır:

  • constructor
  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate
  • getDerivedStateFromProps
  • shouldComponentUpdate
  • render
  • setState yeniləmə funksiyası (ilk arqument)

Bu metodların birdən çox çağrıla bildiyindən bu metodlarda side effektlərin olmaması vacibdir. Bu qaydanı saymadıqda yaddaş sızmaları və etibarsız applikasiya vəziyyəti kimi problemlər yarana bilər. Təəssüf ki, bu problemlərin müəyyən pattern-i olmadığından bu problemləri tutmaq mümkün deyil.

Strict rejim avtomatik olaraq belə side effektləri aşkar edə bilmir. Amma, bu rejim ilə side effektlərin olduğu yerləri tapmaq mümkündür. Bu side effektlərin tapılması üçün, aşağıdakı funksiyalar iki dəfə çağrılır:

  • Klas komponentin constructor funksiyası
  • render funksiyası
  • setState-in yeniləmə funksiyası (ilk arqument)
  • Statik getDerivedStateFromProps lifecycle metodu

Qeyd:

Bu yalnız development zamanı baş verir. Produksiya zamanı lifecycle-lar iki dəfə çağrılmayacaq.

Aşağıdakı kodu nəzərdən keçirin:

class TopLevelRoute extends React.Component {
  constructor(props) {
    super(props);

    SharedApplicationState.recordEvent('ExampleComponent');
  }
}

İlk baxışda bu kod problemsiz görünür. SharedApplicationState.recordEvent funksiyası idempotent olmadıqda komponentin bir neçə dəfə yaranması etibarsız applikasiya vəziyyətinə gətirə bilər. Bu formalı baqlar development zamanı görünməyə bilər.

Komponent konstruktorunda olduğu kimi strict rejim funksiyaları bİlərəkdən iki dəfə çağıraraq bu side effektləri tapa bilir.

Köhnə kontekst API-larının tapılması

Köhnə kontekst API-ının xətalara meyilli olduğundan bu API gələcək böyük versiyada silinəcək. Bu API bütün 16.x buraxılışlarında işləyəcək. Lakin, strict rejimdə aşağıdakı xəbərdarlıq göstəriləcək:

warn legacy context in strict mode

Yeni versiyaya miqrasiya etmək üçün yeni kontekst API sənədinə baxın.