Mulai Cepat

Selamat datang di dokumentasi React! Halaman ini akan memberikan Anda pengenalan tentang 80% konsep React yang akan Anda gunakan sehari-hari.

You will learn

  • Cara membuat dan menyarangkan (nest) komponen-komponen
  • Cara menambahkan markup dan styles
  • Cara menampilkan data
  • Cara me-render kondisi dan daftar (lists)
  • Cara merespons events dan memperbarui layar
  • Cara berbagi data antar komponen

Membuat dan menyarangkan (nesting) komponen

Aplikasi React dibuat dari komponen. Komponen adalah bagian dari UI (user interface, antarmuka pengguna) yang memiliki logika dan tampilan tersendiri. Sebuah komponen dapat berukuran sekecil tombol, atau sebesar seluruh halaman.

Komponen React adalah fungsi JavaScript yang mengembalikan markup:

function MyButton() {
return (
<button>Saya adalah tombol</button>
);
}

Sekarang setelah Anda mendeklarasikan MyButton, Anda dapat menyarangkannya dengan komponen lain:

export default function MyApp() {
return (
<div>
<h1>Selamat datang di aplikasi saya</h1>
<MyButton />
</div>
);
}

Perhatikan bahwa <MyButton /> dimulai dengan huruf kapital. Dengan cara itulah Anda mengetahui bahwa itu adalah sebuah komponen React. Nama komponen React harus selalu dimulai dengan huruf kapital, sedangkan tag HTML harus menggunakan huruf kecil.

Lihatlah hasilnya:

function MyButton() {
  return (
    <button>
      Saya adalah tombol
    </button>
  );
}

export default function MyApp() {
  return (
    <div>
      <h1>Selamat datang di aplikasi saya</h1>
      <MyButton />
    </div>
  );
}

Kata kunci export default menentukan komponen utama di dalam berkas (file). Jika Anda tidak terbiasa dengan beberapa bagian dari sintaksis JavaScript, MDN dan [javascript.info] (https://javascript.info/import-export) memiliki referensi yang bagus.

Menulis markup dengan JSX

Sintaksis markup yang Anda lihat di atas disebut dengan JSX. JSX ini opsional, tetapi sebagian besar proyek React menggunakan JSX untuk kenyamanannya. Semua [alat yang kami rekomendasikan untuk pengembangan lokal] (/learn/installation) mendukung JSX secara langsung.

JSX lebih ketat daripada HTML. Anda harus menutup tag seperti <br />. Komponen Anda juga tidak boleh mengembalikan beberapa tag JSX. Anda harus membungkusnya menjadi induk bersama (shared parent), seperti <div>...</div> atau sebuah pembungkus kosong <>...</>:

function AboutPage() {
return (
<>
<h1>Tentang</h1>
<p>Halo.<br />Apa kabar?</p>
</>
);
}

Jika Anda memiliki banyak HTML untuk dipindahkan (port) ke JSX, Anda dapat menggunakan konverter online..

Menambahkan styles

Di React, Anda menentukan kelas (class) CSS dengan className. Ini bekerja dengan cara yang sama seperti atribut HTML class:

<img className="avatar" />

Kemudian Anda menulis aturan CSS untuk itu di dalam berkas CSS terpisah:

/* Di dalam CSS Anda */
.avatar {
border-radius: 50%;
}

React tidak mengatur (prescribe) bagaimana cara Anda menambahkan berkas CSS. Di dalam kasus yang paling sederhana, Anda akan menambahkan tag <link> ke HTML Anda. Jika Anda menggunakan build tool atau framework, bacalah dokumentasinya untuk mempelajari bagaimana cara menambahkan berkas CSS ke dalam proyek Anda.

Menampilkan data

JSX memungkinkan Anda memasukkan markup ke dalam JavaScript. Kurung kurawal (curly braces) memungkinkan Anda “kembali” (escape back) ke dalam JavaScript sehingga Anda dapat menanamkan (embed) beberapa variabel dari kode Anda dan menampilkannya kepada pengguna. Sebagai contoh, ini akan menampilkan user.name:

return (
<h1>
{user.name}
</h1>
);

You can also “escape into JavaScript” from JSX attributes, but you have to use curly braces instead of quotes. For example, className="avatar" passes the "avatar" string as the CSS class, but src={user.imageUrl} reads the JavaScript user.imageUrl variable value, and then passes that value as the src attribute:

Anda juga dapat “kembali ke JavaScript” dari atribut JSX, tetapi Anda harus menggunakan tanda kurung kurawal daripada tanda kutip (quotes). Sebagai contoh, className="avatar" meneruskan string "avatar" sebagai kelas CSS (CSS class), tetapi src={user.imageUrl} membaca nilai variabel JavaScript user.imageUrl, dan kemudian meneruskan nilai tersebut sebagai atribut src:

return (
<img
className="avatar"
src={user.imageUrl}
/>
);

Anda dapat menaruh ekspresi yang lebih kompleks (complex expressions) di dalam kurung kurawal JSX juga, contohnya, penggabungan string (string concatenation):

const user = {
  name: 'Hedy Lamarr',
  imageUrl: 'https://i.imgur.com/yXOvdOSs.jpg',
  imageSize: 90,
};

export default function Profile() {
  return (
    <>
      <h1>{user.name}</h1>
      <img
        className="avatar"
        src={user.imageUrl}
        alt={'Foto ' + user.name}
        style={{
          width: user.imageSize,
          height: user.imageSize
        }}
      />
    </>
  );
}

Pada contoh di atas, style={{}} bukanlah sintaksis khusus, melainkan objek {} biasa di dalam kurung kurawal JSX. Anda dapat menggunakan atribut style ketika styles Anda bergantung pada variabel JavaScript.

Pe-render-an secara kondisional

Di dalam React, tidak ada sintaksis khusus untuk menulis kondisi. Sebagai gantinya, Anda akan menggunakan teknik yang sama dengan yang Anda gunakan saat menulis kode JavaScript biasa. Sebagai contoh, Anda dapat menggunakan pernyataan (statement) if untuk menyertakan JSX secara kondisional:

let content;
if (isLoggedIn) {
content = <AdminPanel />;
} else {
content = <LoginForm />;
}
return (
<div>
{content}
</div>
);

Jika Anda lebih menyukai kode yang lebih ringkas, Anda dapat menggunakan operator kondisional ?. Tidak seperti if, operator ini bekerja di dalam JSX:

<div>
{isLoggedIn ? (
<AdminPanel />
) : (
<LoginForm />
)}
</div>

Ketika Anda tidak membutuhkan cabang (branch) lain, Anda juga dapat menggunakan sintaksis logika && yang lebih pendek:

<div>
{isLoggedIn && <AdminPanel />}
</div>

Semua pendekatan ini juga dapat digunakan untuk menentukan atribut secara kondisional. Jika Anda tidak terbiasa dengan beberapa sintaksis JavaScript ini, Anda dapat memulai dengan selalu menggunakan if...else.

Me-render daftar (lists)

Anda akan mengandalkan fitur JavaScript seperti perulangan [for] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for) dan [fungsi senarai (array) map()] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) untuk me-render daftar komponen.

Sebagai contoh, katakanlah Anda memiliki serangkaian (array) produk:

const products = [
{ title: 'Kubis', id: 1 },
{ title: 'Bawang Putih', id: 2 },
{ title: 'Apel', id: 3 },
];

Di dalam komponen Anda, gunakan fungsi map() untuk mengubah serangkaian produk menjadi serangkaian item <li>:

const listItems = products.map(product =>
<li key={product.id}>
{product.title}
</li>
);

return (
<ul>{listItems}</ul>
);

Perhatikan bagaimana <li> memiliki atribut key. Untuk setiap item dalam daftar, Anda harus mengoper string atau angka yang secara unik mengidentifikasi item tersebut di antara saudara-saudaranya (siblings). Biasanya, key harus berasal dari data Anda, seperti ID basis data (database). React menggunakan key untuk mengetahui apa yang terjadi jika Anda menyisipkan (insert), menghapus, atau mengurutkan ulang item.

const products = [
  { title: 'Kubis', isFruit: false, id: 1 },
  { title: 'Bawang Putih', isFruit: false, id: 2 },
  { title: 'Apel', isFruit: true, id: 3 },
];

export default function ShoppingList() {
  const listItems = products.map(product =>
    <li
      key={product.id}
      style={{
        color: product.isFruit ? 'magenta' : 'darkgreen'
      }}
    >
      {product.title}
    </li>
  );

  return (
    <ul>{listItems}</ul>
  );
}

Merespon ke event

Anda dapat merespon ke event dengan mendeklarasikan fungsi event handler di dalam komponen Anda:

function MyButton() {
function handleClick() {
alert('Anda mengklik saya!');
}

return (
<button onClick={handleClick}>
Klik saya
</button>
);
}

Perhatikan bagaimana onClick={handleClick} tidak memiliki tanda kurung (parentheses) di bagian akhir! Jangan memanggil fungsi event handler: Anda hanya perlu mengopernya ke bawah. React akan memanggil event handler Anda ketika pengguna mengklik tombol.

Memperbarui layar

Sering kali, Anda ingin komponen Anda “mengingat” beberapa informasi dan menampilkannya. Sebagai contoh, mungkin Anda ingin menghitung berapa kali sebuah tombol diklik. Untuk melakukan hal ini, tambahkan state ke komponen Anda.

Pertama, impor useState dari React:

import { useState } from 'react';

Sekarang Anda dapat mendeklarasikan variabel state di dalam komponen Anda:

function MyButton() {
const [count, setCount] = useState(0);
// ...

Anda akan mendapatkan dua hal dari useState: state saat ini (count), dan fungsi yang memungkinkan Anda memperbaruinya (setCount). Anda dapat memberi nama apa saja, tetapi konvensi yang berlaku adalah menulis [something, setSomething].

Saat pertama kali tombol ditampilkan, count akan menjadi 0 karena Anda mengoper 0 ke useState(). Ketika Anda ingin mengubah state, panggil setCount() dan berikan nilai baru padanya. Mengklik tombol ini akan menambah penghitung (counter):

function MyButton() {
const [count, setCount] = useState(0);

function handleClick() {
setCount(count + 1);
}

return (
<button onClick={handleClick}>
Diklik {count} kali
</button>
);
}

React akan memanggil fungsi komponen Anda lagi. Kali ini, count akan menjadi 1. Kemudian akan menjadi 2. Dan seterusnya.

Jika Anda me-render komponen yang sama beberapa kali, masing-masing akan mendapatkan state-nya sendiri. Klik setiap tombol secara terpisah:

import { useState } from 'react';

export default function MyApp() {
  return (
    <div>
      <h1>Penghitung yang diperbarui secara terpisah</h1>
      <MyButton />
      <MyButton />
    </div>
  );
}

function MyButton() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      Diklik {count} kali
    </button>
  );
}

Perhatikan bagaimana setiap tombol “mengingat” state count-nya sendiri dan tidak memengaruhi tombol lainnya.

Mengggunakan Hooks

Fungsi yang dimulai dengan use disebut dengan Hooks. useState adalah Hook bawaan yang disediakan oleh React. Anda dapat menemukan Hooks bawaan lainnya di referensi API. Anda juga dapat menulis Hooks Anda sendiri dengan menggabungkan Hooks yang sudah ada.

Hooks lebih terbatas dibandingkan fungsi-fungsi lainnya. Anda hanya bisa memanggil Hooks di bagian atas komponen Anda (atau Hooks lainnya). Jika Anda ingin menggunakan useState dalam sebuah kondisi atau perulangan, ekstrak komponen baru dan letakkan di sana.

Sharing data between components

In the previous example, each MyButton had its own independent count, and when each button was clicked, only the count for the button clicked changed:

Diagram showing a tree of three components, one parent labeled MyApp and two children labeled MyButton. Both MyButton components contain a count with value zero.
Diagram showing a tree of three components, one parent labeled MyApp and two children labeled MyButton. Both MyButton components contain a count with value zero.

Initially, each MyButton’s count state is 0

The same diagram as the previous, with the count of the first child MyButton component highlighted indicating a click with the count value incremented to one. The second MyButton component still contains value zero.
The same diagram as the previous, with the count of the first child MyButton component highlighted indicating a click with the count value incremented to one. The second MyButton component still contains value zero.

The first MyButton updates its count to 1

However, often you’ll need components to share data and always update together.

To make both MyButton components display the same count and update together, you need to move the state from the individual buttons “upwards” to the closest component containing all of them.

In this example, it is MyApp:

Diagram showing a tree of three components, one parent labeled MyApp and two children labeled MyButton. MyApp contains a count value of zero which is passed down to both of the MyButton components, which also show value zero.
Diagram showing a tree of three components, one parent labeled MyApp and two children labeled MyButton. MyApp contains a count value of zero which is passed down to both of the MyButton components, which also show value zero.

Initially, MyApp’s count state is 0 and is passed down to both children

The same diagram as the previous, with the count of the parent MyApp component highlighted indicating a click with the value incremented to one. The flow to both of the children MyButton components is also highlighted, and the count value in each child is set to one indicating the value was passed down.
The same diagram as the previous, with the count of the parent MyApp component highlighted indicating a click with the value incremented to one. The flow to both of the children MyButton components is also highlighted, and the count value in each child is set to one indicating the value was passed down.

On click, MyApp updates its count state to 1 and passes it down to both children

Now when you click either button, the count in MyApp will change, which will change both of the counts in MyButton. Here’s how you can express this in code.

First, move the state up from MyButton into MyApp:

export default function MyApp() {
const [count, setCount] = useState(0);

function handleClick() {
setCount(count + 1);
}

return (
<div>
<h1>Counters that update separately</h1>
<MyButton />
<MyButton />
</div>
);
}

function MyButton() {
// ... we're moving code from here ...
}

Kemudian, oper state ke bawah dari MyApp ke setiap MyButton, bersama dengan shared click handler. Anda dapat mengoper informasi ke MyButton menggunakan kurung kurawal JSX, seperti yang sebelumnya Anda lakukan dengan tag bawaan seperti <img>:

export default function MyApp() {
const [count, setCount] = useState(0);

function handleClick() {
setCount(count + 1);
}

return (
<div>
<h1>Counters that update together</h1>
<MyButton count={count} onClick={handleClick} />
<MyButton count={count} onClick={handleClick} />
</div>
);
}

The information you pass down like this is called props. Now the MyApp component contains the count state and the handleClick event handler, and passes both of them down as props to each of the buttons.

Finally, change MyButton to read the props you have passed from its parent component:

function MyButton({ count, onClick }) {
return (
<button onClick={onClick}>
Clicked {count} times
</button>
);
}

When you click the button, the onClick handler fires. Each button’s onClick prop was set to the handleClick function inside MyApp, so the code inside of it runs. That code calls setCount(count + 1), incrementing the count state variable. The new count value is passed as a prop to each button, so they all show the new value. This is called “lifting state up”. By moving state up, you’ve shared it between components.

import { useState } from 'react';

export default function MyApp() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>Counters that update together</h1>
      <MyButton count={count} onClick={handleClick} />
      <MyButton count={count} onClick={handleClick} />
    </div>
  );
}

function MyButton({ count, onClick }) {
  return (
    <button onClick={onClick}>
      Clicked {count} times
    </button>
  );
}

Langkah Selanjutnya

Sekarang, Anda telah mengetahui dasar-dasar cara menulis kode React!

Lihat Tutorial untuk mempraktikkannya dan membangun aplikasi mini pertama Anda dengan React.