<StrictMode> memungkinkan Anda menemukan bug umum di komponen Anda lebih awal selama pengembangan.

<StrictMode>
<App />
</StrictMode>

Referensi

<StrictMode>

Gunakan StrictMode untuk mengaktifkan perilaku pengembangan dan peringatan tambahan untuk pohon komponen di dalamnya:

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';

const root = createRoot(document.getElementById('root'));
root.render(
<StrictMode>
<App />
</StrictMode>
);

Lihat contoh lainnya di bawah.

Strict Mode mengaktifkan perilaku-perilaku pengembangan berikut:

Props

StrictMode tidak menerima props.

Peringatan

  • Tidak ada cara untuk keluar dari Strict Mode di dalam pohon yang terbungkus dalam <StrictMode>. Ini memberi Anda keyakinan bahwa semua komponen di dalam <StrictMode> telah diperiksa. Jika dua tim yang bekerja pada suatu produk tidak setuju apakah mereka menganggap pemeriksaan itu berharga, mereka harus mencapai konsensus atau memindahkan <StrictMode> ke bawah dalam hierarki.

Penggunaan

Mengaktifkan Strict Mode untuk seluruh aplikasi

Strict Mode memungkinkan pemeriksaan tambahan khusus pengembangan untuk seluruh pohon komponen di dalam komponen <StrictMode>. Pemeriksaan ini membantu Anda menemukan bug umum di komponen Anda di awal proses pengembangan.

Untuk mengaktifkan Strict Mode pada seluruh aplikasi Anda, bungkus komponen akar Anda dengan <StrictMode> ketika Anda me-render:

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';

const root = createRoot(document.getElementById('root'));
root.render(
<StrictMode>
<App />
</StrictMode>
);

Kami merekomendasikan untuk membungkus seluruh aplikasi Anda dalam Strict Mode, terutama untuk aplikasi yang baru dibuat. Jika Anda menggunakan framework yang memanggil createRoot untuk Anda, periksa dokumentasinya untuk cara mengaktifkan Strict Mode.

Meskipun pemeriksaan Strict Mode hanya berjalan dalam pengembangan,, pemeriksaan ini membantu Anda menemukan bug yang sudah ada dalam kode Anda, tetapi sulit untuk direproduksi secara andal dalam produksi. Strict Mode memungkinkan Anda memperbaiki bug sebelum pengguna melaporkannya.

Catatan

Strict Mode mengaktifkan perilaku-perilaku pengembangan berikut:

Semua pemeriksaan ini hanya untuk pengembangan dan tidak memengaruhi build produksi.


Mengaktifkan Strict Mode untuk bagian dari aplikasi

Anda juga dapat mengaktifkan Strict Mode untuk setiap bagian dari aplikasi Anda:

import { StrictMode } from 'react';

function App() {
return (
<>
<Header />
<StrictMode>
<main>
<Sidebar />
<Content />
</main>
</StrictMode>
<Footer />
</>
);
}

Dalam contoh ini, pemeriksaan Strict Mode tidak akan dijalankan terhadap komponen Header dan Footer. Namun, mereka akan berjalan di Sidebar dan Content, serta semua komponen di dalamnya, tidak peduli seberapa dalam.


Memperbaiki bug yang ditemukan oleh rendering ganda dalam pengembangan

React mengasumsikan bahwa setiap komponen yang Anda tulis adalah fungsi murni. Ini berarti bahwa komponen React yang Anda tulis harus selalu mengembalikan JSX yang sama dengan masukan yang sama (props, state, and context).

Komponen yang melanggar aturan ini berperilaku tidak terduga dan menyebabkan bug. Untuk membantu Anda menemukan kode tidak murni secara tidak sengaja, Strict Mode memanggil beberapa fungsi Anda (hanya yang seharusnya murni) dua kali dalam pengembangan. Ini termasuk:

Jika fungsi murni, menjalankannya dua kali tidak mengubah perilakunya karena fungsi murni menghasilkan hasil yang sama setiap waktu. Namun, jika suatu fungsi tidak murni (misalnya, memutasikan data yang diterimanya), menjalankannya dua kali cenderung terlihat (itulah yang membuatnya tidak murni!) Ini membantu Anda menemukan dan memperbaiki bug lebih awal.

Berikut adalah contoh untuk mengilustrasikan bagaimana rendering ganda dalam Strict Mode membantu Anda menemukan bug lebih awal.

Komponen StoryTray mengambil larik stories dan menambahkan satu item terakhir “Create Story” di bagian akhir:

export default function StoryTray({ stories }) {
  const items = stories;
  items.push({ id: 'create', label: 'Create Story' });
  return (
    <ul>
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}

Ada kesalahan pada kode di atas. Namun, mudah untuk terlewatkan karena hasil awal terlih benar.

Kesalahan ini akan semakin terlihat jika komponen StoryTray me-render ulang beberapa kali. Misalnya, mari buat StoryTray di-render ulang dengan warna latar berbeda setiap kali Anda mengarahkan kursor ke atasnya:

import { useState } from 'react';

export default function StoryTray({ stories }) {
  const [isHover, setIsHover] = useState(false);
  const items = stories;
  items.push({ id: 'create', label: 'Create Story' });
  return (
    <ul
      onPointerEnter={() => setIsHover(true)}
      onPointerLeave={() => setIsHover(false)}
      style={{
        backgroundColor: isHover ? '#ddd' : '#fff'
      }}
    >
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}

Perhatikan bagaimana setiap kali Anda mengarahkan kursor ke komponen StoryTray, “Buat Cerita” akan ditambahkan ke daftar lagi. Maksud dari kode tersebut adalah untuk menambahkannya sekali di bagian akhir. Tapi StoryTray secara langsung memodifikasi larik stories dari props. Setiap kali StoryTray me-render, ia menambahkan “Buat Cerita” lagi di akhir larik yang sama. Dengan kata lain, StoryTray bukan fungsi murni—menjalankannya berkali-kali menghasilkan hasil yang berbeda.

Untuk memperbaiki masalah ini, Anda dapat membuat salinan larik, dan memodifikasi salinan tersebut, bukan yang asli:

export default function StoryTray({ stories }) {
const items = stories.slice(); // Clone the array
// ✅ Good: Pushing into a new array
items.push({ id: 'create', label: 'Create Story' });

Ini akan membuat fungsi StoryTray murni. Setiap kali dipanggil, ini hanya akan memodifikasi salinan baru dari larik, dan tidak akan memengaruhi objek atau variabel eksternal apa pun. Ini menyelesaikan bug, tetapi Anda harus membuat komponen di-render ulang lebih sering sebelum menjadi jelas bahwa ada yang salah dengan perilakunya.

Dalam contoh aslinya, bug itu tidak terlihat jelas. Sekarang mari kita bungkus kode asli (penuh dengan bug) <StrictMode>:

export default function StoryTray({ stories }) {
  const items = stories;
  items.push({ id: 'create', label: 'Create Story' });
  return (
    <ul>
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}

Strict Mode selalu memanggil fungsi rendering Anda dua kali, sehingga Anda dapat langsung melihat kesalahannya (“Create Story” muncul dua kali). Ini memungkinkan Anda melihat kesalahan seperti itu di awal proses. Saat Anda memperbaiki komponen untuk di-render dalam Strict Mode, Anda juga memperbaiki banyak kemungkinan memproduksi bug di masa mendatang seperti fungsi hover sebelumnya:

import { useState } from 'react';

export default function StoryTray({ stories }) {
  const [isHover, setIsHover] = useState(false);
  const items = stories.slice(); // Clone the array
  items.push({ id: 'create', label: 'Create Story' });
  return (
    <ul
      onPointerEnter={() => setIsHover(true)}
      onPointerLeave={() => setIsHover(false)}
      style={{
        backgroundColor: isHover ? '#ddd' : '#fff'
      }}
    >
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}

Tanpa Strict Mode, mudah untuk melewatkan bug sampai Anda menambahkan lebih banyak render ulang. Strict Mode membuat bug yang sama segera muncul. Strict Mode membantu Anda menemukan bug sebelum mendorongnya ke tim dan pengguna Anda.

Baca lebih lanjut tentang menjaga kemurnian komponen.

Catatan

Jika Anda telah menginstal React DevTools, setiap panggilan console.log selama panggilan render kedua akan tampak sedikit redup. React DevTools juga menawarkan pengaturan (dinonaktifkan secara default) untuk menekannya sepenuhnya.


Memperbaiki bug yang ditemukan dengan menjalankan kembali Efek dalam pengembangan

Strict Mode juga dapat membantu menemukan bug di Effects.

Setiap Efek memiliki beberapa setup code dan mungkin memiliki beberapa kode pembersihan. Biasanya, React memanggil setup ketika komponen mounts (ditambahkan ke layar) dan memanggil pembersihan ketika komponen unmounts (dihapus dari layar). React kemudian memanggil pembersihan dan setup lagi jika dependensinya berubah setelah render terakhir.

Saat Strict Mode aktif, React juga akan menjalankan satu siklus setup+pembersihan tambahan dalam pengembangan untuk setiap Efek. Ini mungkin terasa mengejutkan, tetapi membantu mengungkapkan bug tak kentara yang sulit ditangkap secara manual.

Berikut adalah contoh untuk mengilustrasikan bagaimana menjalankan kembali Efek dalam Strict Mode membantu Anda menemukan bug lebih awal.

Pertimbangkan contoh ini yang menghubungkan komponen ke obrolan:

import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';
const roomId = 'general';

export default function ChatRoom() {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
  }, []);
  return <h1>Welcome to the {roomId} room!</h1>;
}

Ada masalah dengan kode ini, tetapi mungkin tidak segera jelas.

Untuk memperjelas masalah, mari terapkan sebuah fitur. Pada contoh di bawah, roomId tidak di-hardcode. Sebagai gantinya, pengguna dapat memilih roomId yang ingin mereka sambungkan dari dropdown. Klik “Buka obrolan” lalu pilih ruang obrolan yang berbeda satu per satu. Lacak jumlah koneksi aktif di konsol:

import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
  }, [roomId]);

  return <h1>Welcome to the {roomId} room!</h1>;
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  const [show, setShow] = useState(false);
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <button onClick={() => setShow(!show)}>
        {show ? 'Close chat' : 'Open chat'}
      </button>
      {show && <hr />}
      {show && <ChatRoom roomId={roomId} />}
    </>
  );
}

Anda akan melihat bahwa jumlah koneksi aktif selalu terus bertambah. Dalam aplikasi nyata, ini akan menyebabkan masalah kinerja dan jaringan. Masalahnya adalah Efek Anda tidak memiliki fungsi pembersihan:

useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => connection.disconnect();
}, [roomId]);

Sekarang Efek Anda “membersihkan” setelahnya sendiri dan menghancurkan koneksi yang sudah tidak digunakan, kebocorannya teratasi. Namun, perhatikan bahwa masalahnya tidak terlihat hingga Anda menambahkan lebih banyak fitur (select box).

Dalam contoh aslinya, bug-nya tidak terlihat jelas. Sekarang mari bungkus kode asli (memiliki bug) dalam <StrictMode>:

import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';
const roomId = 'general';

export default function ChatRoom() {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
  }, []);
  return <h1>Welcome to the {roomId} room!</h1>;
}

Dengan Strict Mode, Anda segera melihat bahwa ada masalah (jumlah koneksi aktif melonjak menjadi 2). Strict Mode menjalankan siklus setup+pembersihan ekstra untuk setiap Efek. Efek ini tidak memiliki logika pembersihan, sehingga membuat koneksi ekstra tetapi tidak menghancurkan. Ini adalah petunjuk bahwa Anda melewatkan fungsi pembersihan.

Strict Mode memungkinkan Anda melihat kesalahan seperti itu di awal proses. Saat Anda memperbaiki Efek dengan menambahkan fungsi pembersihan dalam Strict Mode, Anda juga memperbaiki banyak kemungkinan memproduksi bug di masa mendatang seperti select box sebelumnya:

import { useState, useEffect } from 'react';
import { createConnection } from './chat.js';

const serverUrl = 'https://localhost:1234';

function ChatRoom({ roomId }) {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]);

  return <h1>Welcome to the {roomId} room!</h1>;
}

export default function App() {
  const [roomId, setRoomId] = useState('general');
  const [show, setShow] = useState(false);
  return (
    <>
      <label>
        Choose the chat room:{' '}
        <select
          value={roomId}
          onChange={e => setRoomId(e.target.value)}
        >
          <option value="general">general</option>
          <option value="travel">travel</option>
          <option value="music">music</option>
        </select>
      </label>
      <button onClick={() => setShow(!show)}>
        {show ? 'Close chat' : 'Open chat'}
      </button>
      {show && <hr />}
      {show && <ChatRoom roomId={roomId} />}
    </>
  );
}

Perhatikan bagaimana jumlah koneksi aktif di konsol tidak bertambah lagi.

Tanpa Strict Mode, mudah untuk luput bahwa Efek Anda perlu dibersihkan. Dengan menjalankan setup → cleanup → setup alih-alih setup untuk Efek Anda dalam pengembangan, Strict Mode membuat logika pembersihan yang hilang menjadi lebih terlihat.

Baca lebih lanjut tentang menerapkan pembersihan Efek.


Memperbaiki peringatan penghentian yang diaktifkan oleh Strict Mode

React memperingatkan jika beberapa komponen dimana pun di dalam tree <StrictMode> menggunakan salah satu API yang telah usang:

API ini terutama digunakan di masa lalu class components jadi jarang muncul di aplikasi modern.