Skip to content

Concurrent Mode Patterns Translation #181

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 35 additions & 34 deletions content/docs/concurrent-mode-patterns.md
Original file line number Diff line number Diff line change
@@ -15,63 +15,62 @@ next: concurrent-mode-adoption.html

<div class="scary">

>Caution:
>Perhatian:
>
>This page describes **experimental features that are [not yet available](/docs/concurrent-mode-adoption.html) in a stable release**. Don't rely on experimental builds of React in production apps. These features may change significantly and without a warning before they become a part of React.
>Laman ini menjelaskan **fitur eksperimental yang [belum tersedia](/docs/concurrent-mode-adoption.html) dalam versi rilis yang stabil**. Jangan mengandalkan _build_ eksperimental dalam aplikasi React versi produksi. Fitur ini dapat berubah secara signifikan dan tanpa peringatan sebelum menjadi bagian dari React.
>
>This documentation is aimed at early adopters and people who are curious. **If you're new to React, don't worry about these features** -- you don't need to learn them right now. For example, if you're looking for a data fetching tutorial that works today, read [this article](https://www.robinwieruch.de/react-hooks-fetch-data/) instead.
>Dokumentasi ini ditujukan untuk pengguna awal dan orang-orang yang penasaran. **Kalau anda baru menggunakan React, jangan khawatir tentang fitur ini** -- anda tidak perlu mempelajarinya sekarang.

</div>

Usually, when we update the state, we expect to see changes on the screen immediately. This makes sense because we want to keep our app responsive to user input. However, there are cases where we might prefer to **defer an update from appearing on the screen**.
Biasanya, ketika kita mengubah state, kita akan langsung melihat perubahannya di layar. Ini masuk akal karena kita ingin aplikasi responsif terhadap input user. Tetapi, mungkin ada kasus dimana kita lebih memilih untuk **menunda perubahan yang terjadi di layar**

For example, if we switch from one page to another, and none of the code or data for the next screen has loaded yet, it might be frustrating to immediately see a blank page with a loading indicator. We might prefer to stay longer on the previous screen. Implementing this pattern has historically been difficult in React. Concurrent Mode offers a new set of tools to do that.

- [Transitions](#transitions)
- [Wrapping setState in a Transition](#wrapping-setstate-in-a-transition)
- [Adding a Pending Indicator](#adding-a-pending-indicator)
- [Reviewing the Changes](#reviewing-the-changes)
- [Where Does the Update Happen?](#where-does-the-update-happen)
- [Transitions Are Everywhere](#transitions-are-everywhere)
Contohnya, ketika kita pindah laman, dan belum ada data yang tersedia untuk laman selanjutnya, mungkin kita akan merasa frustasi ketika melihat laman dengan loading. Kita mungkin lebih memilih untuk tetap berada di laman sebelumnya. Meng-implementasi pola ini secara historis sulit dalam React. Concurrent Mode menawarkan seperangkat alat baru untuk melakukan itu.
- [Transisi](#transitions)
- [Setstate didalam transisi](#wrapping-setstate-in-a-transition)
- [Menambah indikator tunggu](#adding-a-pending-indicator)
- [Review perubahan](#reviewing-the-changes)
- [Dimana perubahan terjadi?](#where-does-the-update-happen)
- [Transisi disetiap tempat](#transitions-are-everywhere)
- [Baking Transitions Into the Design System](#baking-transitions-into-the-design-system)
- [The Three Steps](#the-three-steps)
- [Tiga Langkah](#the-three-steps)
- [Default: Receded → Skeleton → Complete](#default-receded-skeleton-complete)
- [Preferred: Pending → Skeleton → Complete](#preferred-pending-skeleton-complete)
- [Wrap Lazy Features in `<Suspense>`](#wrap-lazy-features-in-suspense)
- [Suspense Reveal “Train”](#suspense-reveal-train)
- [Delaying a Pending Indicator](#delaying-a-pending-indicator)
- [Recap](#recap)
- [Other Patterns](#other-patterns)
- [Splitting High and Low Priority State](#splitting-high-and-low-priority-state)
- [Cara lain](#other-patterns)
- [Memisahkan state dengan prioritas tinggi dan rendah](#splitting-high-and-low-priority-state)
- [Deferring a Value](#deferring-a-value)
- [SuspenseList](#suspenselist)
- [Next Steps](#next-steps)
- [Selanjutnya](#next-steps)

## Transitions {#transitions}
## Transisi {#transitions}

Let's revisit [this demo](https://codesandbox.io/s/infallible-feather-xjtbu) from the previous page about [Suspense for Data Fetching](/docs/concurrent-mode-suspense.html).
Mari buka kembali [demo berikut](https://codesandbox.io/s/infallible-feather-xjtbu) dari the laman sebelumnya mengenai [Suspense for Data Fetching](/docs/concurrent-mode-suspense.html).

When we click the "Next" button to switch the active profile, the existing page data immediately disappears, and we see the loading indicator for the whole page again. We can call this an "undesirable" loading state. **It would be nice if we could "skip" it and wait for some content to load before transitioning to the new screen.**
Ketika kita klik Tombol "Next" untuk mengubah profil aktif, data laman sebelumnya langsung menghilang, dan kita melihat indikator loading untuk seluruh laman lagi. Kita bisa menyebut hal ini loading state yang "tidak diinginkan". **Akan lebih baik jika kita bisa "melewatinya" dan menunggu konten tersebut selesai di load sebelum pindah ke laman baru**

React offers a new built-in `useTransition()` Hook to help with this.
React punya Hook khusus `useTransition()` untuk menangani masalah ini.

We can use it in three steps.
Kita bisa menggunakannya dengan 3 langkah.

First, we'll make sure that we're actually using Concurrent Mode. We'll talk more about [adopting Concurrent Mode](/docs/concurrent-mode-adoption.html) later, but for now it's sufficient to know that we need to use `ReactDOM.createRoot()` rather than `ReactDOM.render()` for this feature to work:
Pertama, Kita harus menggunakan Concurrent Mode. Kita akan membahas lebih lanjut tentang [mengadopsi Concurrent Mode](/docs/concurrent-mode-adoption.html) lain waktu, untuk sekarang kita hanya perlu tahu kalau kita akan menggunakan `ReactDOM.createRoot()` daripada `ReactDOM.render()` agar fitur berikut dapat bekerja:

```js
const rootElement = document.getElementById("root");
// Opt into Concurrent Mode
ReactDOM.createRoot(rootElement).render(<App />);
```

Next, we'll add an import for the `useTransition` Hook from React:
Selanjutnya kita import hook`useTransition` dari React:

```js
import React, { useState, useTransition, Suspense } from "react";
```

Finally, we'll use it inside the `App` component:
Terakhir, kita pakai hook tersebut di dalam komponen `App`:

```js{3-5}
function App() {
@@ -82,18 +81,18 @@ function App() {
// ...
```

**By itself, this code doesn't do anything yet.** We will need to use this Hook's return values to set up our state transition. There are two values returned from `useTransition`:
**Dengan sendirinya, kode ini tidak melakukan apapun.** Kita akan menggunakan nilai return dari Hook ini untuk mempersiapkan transisi state kita. Ada dua nilai yang di return dari `useTransition`":

* `startTransition` is a function. We'll use it to tell React *which* state update we want to defer.
* `isPending` is a boolean. It's React telling us whether that transition is ongoing at the moment.
* `startTransition` adalah fungsi. Fungsi ini akan kita gunakan untuk memberi tahu React state *mana* yang ingin kita tunda.
* `isPending` adalah boolean. React memberi tahu apakah transisi sedang terjadi atau tidak.

We will use them right below.
Kita akan menggunakannya seperti berikut.

Note we passed a configuration object to `useTransition`. Its `timeoutMs` property specifies **how long we're willing to wait for the transition to finish**. By passing `{timeoutMs: 3000}`, we say "If the next profile takes more than 3 seconds to load, show the big spinner -- but before that timeout it's okay to keep showing the previous screen".
Kita menggunakan objek konfigurasi ke `useTransition`. Properti `timeoutMs` menspesifikasi **berapa lama kita ingin menunggu transisi untuk selesai**. Dengan mengoper `{timeoutMs: 3000}`, berarti kita mengatakan "Jika profil perlu lebih dari 3 detik untuk load, tampilkan loading berputar -- tapi sebelum timeout kita bisa tetap memperlihatkan layar sebelumnya".

### Wrapping setState in a Transition {#wrapping-setstate-in-a-transition}
### Setstate didalam transisi {#wrapping-setstate-in-a-transition}

Our "Next" button click handler sets the state that switches the current profile in the state:
Handler klik tombol "Next" kita, mengubah state yang mengganti profile saat ini:

```js{4}
<button
@@ -104,7 +103,7 @@ Our "Next" button click handler sets the state that switches the current profile
>
```

We'll wrap that state update into `startTransition`. That's how we tell React **we don't mind React delaying that state update** if it leads to an undesirable loading state:
Kita akan membungkus perubahan state tersebut didalam `startTransition`. Dengan begitu, kita memberitahu React untuk **Boleh delay update state tersebut** jika perubahan tersebut membuat loading state yang tidak diinginkan:

```js{3,6}
<button
@@ -117,13 +116,15 @@ Our "Next" button click handler sets the state that switches the current profile
>
```

**[Try it on CodeSandbox](https://codesandbox.io/s/musing-driscoll-6nkie)**
**[Coba di CodeSandbox](https://codesandbox.io/s/musing-driscoll-6nkie)**

Press "Next" a few times. Notice it already feels very different. **Instead of immediately seeing an empty screen on click, we now keep seeing the previous page for a while.** When the data has loaded, React transitions us to the new screen.
Tekan "Next" beberapa kali. Jika diperhatikan, akan terasa bedanya. **Daripada langsung melihat layar kosong ketika klik, sekarang kita melihat layar sebelumnya untuk beberapa saat.** Ketika data sudah diload, React mengarahkan kita ke layar baru.

If we make our API responses take 5 seconds, [we can confirm](https://codesandbox.io/s/relaxed-greider-suewh) that now React "gives up" and transitions anyway to the next screen after 3 seconds. This is because we passed `{timeoutMs: 3000}` to `useTransition()`. For example, if we passed `{timeoutMs: 60000}` instead, it would wait a whole minute.
Jika kita buat API response untuk menunggu selama 5 detik, [kita bisa memastikan](https://codesandbox.io/s/relaxed-greider-suewh) kalau React "menyerah" dan langsung mengarahkan kita ke layar selanjutnya setelah 3 detik. Ini karena kita telah melewati batas `{timeoutMs: 3000}` untuk `useTransition()`. Contohnya, jika kita set `{timeoutMs: 60000}`, React akan menunggu selama semenit penuh.

### Adding a Pending Indicator {#adding-a-pending-indicator}
### Menambah indikator tunggu {#adding-a-pending-indicator}

There's still something that feels broken about [our last example](https://codesandbox.io/s/musing-driscoll-6nkie). Sure, it's nice not to see a "bad" loading state. **But having no indication of progress at all feels even worse!** When we click "Next", nothing happens and it feels like the app is broken.