We want to hear from you!Take our 2021 Community Survey!
This site is no longer updated.Go to react.dev

Mode Ketat (Strict Mode)

These docs are old and won’t be updated. Go to react.dev for the new React docs.

These new documentation pages teach modern React and include live examples:

Mode Ketat (StrictMode) merupakan alat untuk menyoroti potensi masalah dalam aplikasi. Seperti halnya Fragment, StrictMode tidak me-render antarmuka yang tampak. Mode ini mengaktifkan pemeriksaan dan peringatan ekstra untuk turunannya.

Catatan:

Pemeriksaan mode ketat hanya berjalan dalam mode pengembangan. Mode ini tidak berdampak dalam build produksi.

Anda bisa mengaktifkan mode ketat untuk berbagai bagian dalam aplikasi. Misalnya:

import React from 'react';

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

Pada contoh di atas, pemeriksaan mode ketat tidak akan dijalankan dalam komponen Header dan Footer. Namun, ComponentOne dan ComponentTwo, beserta semua turunannya akan diperiksa.

Saat ini Mode Ketat StrictMode membantu dalam:

Fungsionalitas lain akan ditambahkan dalam rilis React masa mendatang.

Identifikasi komponen yang mengandung unsafe lifecycle

Seperti yang dijelaskan dalam postingan blog ini, beberapa metode lifecycle yang bersifat legacy tidak aman digunakan dalam aplikasi React asinkronus. Namun, jika aplikasi Anda menggunakan library pihak ketiga, sangat sulit untuk memastikan bahwa lifecycle ini benar-benar tidak digunakan. Mode ketat bisa membantu Anda dalam hal ini.

Saat mode ketat diaktifkan, React mengompilasi daftar semua komponen kelas yang menggunakan unsafe lifecycle dan mencatatkan pesan peringatan dengan informasi tentang komponen tersebut, misalnya:

strict mode unsafe lifecycles warning

Mengatasi masalah yang diidentifikasi oleh mode ketat sekarang juga akan mempermudah Anda untuk memanfaatkan proses render asinkronus dalam rilis React masa mendatang.

Peringatan atas penggunaan API string ref legacy

Sebelumnya, React menyediakan dua cara untuk mengelola ref: API string ref legacy dan API callback. Walau API string ref lebih nyaman digunakan, API ini memiliki beberapa kelemahan sehingga rekomendasi resmi kami adalah menggunakan bentuk callback.

React 16.3 menambahkan opsi ketiga yang menawarkan kenyamanan string ref tanpa kelemahan tersebut:

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();  }
}

Dengan penambahan object ref sebagai pengganti untuk string ref, mode ketat kini memperingatkan tentang penggunaan string ref.

Catatan:

Callback ref akan terus didukung selain API baru createRef.

Anda tidak perlu mengganti callback ref dalam komponen Anda. API ini sedikit lebih fleksibel, jadi API ini akan tetap menjadi fitur lanjutan.

Pelajari lebih lanjut tentang API baru createRef di sini.

Peringatan atas penggunaan findDOMNode yang usang

Sebelumnya React telah mendukung findDOMNode untuk pencarian simpul DOM dalam pohon berdasarkan instance kelas. Pada umumnya hal ini tidak perlu dilakukan karena Anda bisa menyertakan ref langsung ke simpul DOM.

findDOMNode juga dapat digunakan dalam komponen kelas. Namun cara ini melanggar level abstraksi dengan mengizinkan induk untuk meminta turunan tertentu agar di-render. Hal ini menciptakan risiko dalam proses refactor, yaitu Anda tidak bisa mengubah detail implementasi sebuah komponen karena induk mungkin bisa mengubah simpul DOM-nya. findDOMNode hanya akan mengembalikan anak pertama. Namun dengan menggunakan Fragment, sebuah komponen dimungkinkan untuk me-render beberapa simpul DOM sekaligus. findDOMNode merupakan API baca sekali saja. API ini memberikan jawaban hanya pada saat diminta. Jika komponen anak me-render simpul yang berbeda, tidak ada cara untuk menangani perubahan ini. Dengan alasan ini findDOMNode hanya berfungsi jika komponen selalu mengembalikan sebuah simpul DOM yang tidak pernah berubah.

Anda bisa membuat hal ini menjadi eksplisit dengan meneruskan sebuah ref ke komponen khusus Anda, dan meneruskannya ke DOM menggunakan penerusan ref.

Anda juga bisa menambahkan simpul DOM pembungkus dalam komponen Anda dan menyertakan ref langsung kepadanya.

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

Catatan:

Dalam CSS, atribut display: contents bisa digunakan jika Anda tidak ingin simpul menjadi bagian dari layout.

Pendeteksian atas efek samping yang tidak diharapkan

Secara mendasar, React bekerja dalam dua tahap:

  • Tahap render menentukan perubahan apa yang perlu terjadi, misalnya untuk DOM. Dalam tahap ini, React memanggil render lalu membandingkannya dengan hasil render sebelumnya.
  • Tahap commit yang terjadi saat React menerapkan perubahan yang ada. Pada kasus DOM, ini yang terjadi saat React menyisipkan, memperbarui, dan menghapus simpul DOM. React juga memanggil lifecycle seperti componentDidMount dan componentDidUpdate dalam tahap ini.

Tahap commit umumnya berlangsung sangat cepat, tetapi proses render bisa sangat lambat. Dengan alasan ini, mode asinkronus mendatang (yang masih belum diaktifkan secara default)akan memecah proses render menjadi beberapa bagian, menjeda dan melanjutkan proses untuk mencegah pemblokiran oleh browser. Ini berarti React mungkin memanggil lifecycle render lebih dari satu kali sebelum memanggil commit, atau memanggil render tanpa sama sekali memanggil commit (karena ada kesalahan atau adanya interupsi dari proritas yang lebih tinggi).

Lifecyle tahap render menyertakan metode komponen kelas berikut:

  • constructor
  • componentWillMount (or UNSAFE_componentWillMount)
  • componentWillReceiveProps (or UNSAFE_componentWillReceiveProps)
  • componentWillUpdate (or UNSAFE_componentWillUpdate)
  • getDerivedStateFromProps
  • shouldComponentUpdate
  • render
  • Fungsi pembaruan setState (argumen pertama)

Oleh karena metode di atas mungkin dipanggil lebih dari satu kali, sangat penting bagi metode tersebut untuk tidak menimbulkan efek samping. Pengabaian atas aturan ini bisa menyebabkan berbagai macam masalah, termasuk kebocoran memori dan state aplikasi yang tidak valid. Sayangnya, mungkin sangat sulit untuk mendeteksi masalah tersebut karena masalahnya mungkin bersifat non-deterministik.

Mode ketat tidak bisa mendeteksi efek samping secara otomatis, tetapi bisa membantu Anda untuk menemukannya dengan membuatnya menjadi lebih deterministik. Ini dilakukan dengan memanggil metode berikut dua kali secara sengaja:

  • Metode constructor, render, dan shouldComponentUpdate komponen kelas
  • Metode statis getDerivedStateFromProps komponen kelas
  • Isi komponen fungsi
  • Fungsi pembaruan state (argumen pertama setState)
  • Fungsi yang dioper ke useState, useMemo, atau useReducer

Catatan:

Ini hanya berlaku dalam mode pengembangan. Lifecycle tidak akan dipanggil dua kali dalam mode produksi.

Sebagai contoh, kita gunakan kode berikut:

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

    SharedApplicationState.recordEvent('ExampleComponent');
  }
}

Sekilas, kode tersebut tampak tidak mengandung masalah. Tetapi jika SharedApplicationState.recordEvent tidak bersifat idempotent, maka pembuatan instance komponen ini secara berulang kali akan berujung pada state aplikasi yang tidak valid. Bug yang tidak kentara mungkin tidak muncul dalam pengembangan atau mungkin terjadi secara tidak konsisten, dan pada akhirnya cenderung diabaikan.

Dengan memanggil metode dua kali secara sengaja seperti konstruktor komponen, mode ketat membuat pola di atas lebih mudah ditemukan.

Note:

In React 17, React automatically modifies the console methods like console.log() to silence the logs in the second call to lifecycle functions. However, it may cause undesired behavior in certain cases where a workaround can be used.

Starting from React 18, React does not suppress any logs. However, if you have React DevTools installed, the logs from the second call will appear slightly dimmed. React DevTools also offers a setting (off by default) to suppress them completely.

Pendeteksian API context legacy

API context legacy sangat rentan dari kesalahan dan akan dihapus dalam versi mayor mendatang. API ini masih berfungsi dalam semua rilis 16.x tetapi akan menampilkan pesan peringatan berikut dalam mode ketat:

warn legacy context in strict mode

Baca dokumentasi tentang API context yang baru untuk membantu proses migrasi ke versi yang baru.

Ensuring reusable state

In the future, we’d like to add a feature that allows React to add and remove sections of the UI while preserving state. For example, when a user tabs away from a screen and back, React should be able to immediately show the previous screen. To do this, React will support remounting trees using the same component state used before unmounting.

This feature will give React better performance out-of-the-box, but requires components to be resilient to effects being mounted and destroyed multiple times. Most effects will work without any changes, but some effects do not properly clean up subscriptions in the destroy callback, or implicitly assume they are only mounted or destroyed once.

To help surface these issues, React 18 introduces a new development-only check to Strict Mode. This new check will automatically unmount and remount every component, whenever a component mounts for the first time, restoring the previous state on the second mount.

To demonstrate the development behavior you’ll see in Strict Mode with this feature, consider what happens when React mounts a new component. Without this change, when a component mounts, React creates the effects:

* React mounts the component.
  * Layout effects are created.
  * Effects are created.

With Strict Mode starting in React 18, whenever a component mounts in development, React will simulate immediately unmounting and remounting the component:

* React mounts the component.
    * Layout effects are created.
    * Effects are created.
* React simulates effects being destroyed on a mounted component.
    * Layout effects are destroyed.
    * Effects are destroyed.
* React simulates effects being re-created on a mounted component.
    * Layout effects are created
    * Effect setup code runs

On the second mount, React will restore the state from the first mount. This feature simulates user behavior such as a user tabbing away from a screen and back, ensuring that code will properly handle state restoration.

When the component unmounts, effects are destroyed as normal:

* React unmounts the component.
  * Layout effects are destroyed.
  * Effects are destroyed.

Unmounting and remounting includes:

  • componentDidMount
  • componentWillUnmount
  • useEffect
  • useLayoutEffect
  • useInsertionEffect

Note:

This only applies to development mode, production behavior is unchanged.

For help supporting common issues, see:

Is this page useful?Edit halaman ini