From 1d9264417c8f3a9866183a35c0afb6bcf008a6d7 Mon Sep 17 00:00:00 2001 From: Muhammad Ridwan Date: Mon, 1 May 2023 20:56:07 +0700 Subject: [PATCH 1/5] docs: translation for passing data deeply with context --- .../learn/passing-data-deeply-with-context.md | 250 +++++++++--------- 1 file changed, 125 insertions(+), 125 deletions(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index 45c5e77da..31eacc8ff 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -1,33 +1,33 @@ --- -title: Passing Data Deeply with Context +title: Mengoper Data Secara Mendalam dengan Context --- -Usually, you will pass information from a parent component to a child component via props. But passing props can become verbose and inconvenient if you have to pass them through many components in the middle, or if many components in your app need the same information. *Context* lets the parent component make some information available to any component in the tree below it—no matter how deep—without passing it explicitly through props. +Biasanya, Anda akan mengoper informasi dari komponen induk ke komponen anak melalui *props*. Tapi mengoper *props* bisa menjadi bertele-tele dan merepotkan jika Anda harus mengopernya melalui banyak komponen di tengah-tengah, atau jika banyak komponen di aplikasi Anda membutuhkan informasi yang sama. *Context* memungkinkan komponen induk untuk membuat beberapa informasi tersedia di komponen lain di pohon di bawahnya—tidak peduli seberapa dalam—tanpa mengopernya secara eksplisit melalui *props*. -- What "prop drilling" is -- How to replace repetitive prop passing with context -- Common use cases for context -- Common alternatives to context +- Apa itu "*prop drilling*" +- Bagaimana cara mengganti pengiriman *props* yang berulang dengan *context* +- Kasus umum untuk penggunaan *context* +- Alternatif umum untuk *context* -## The problem with passing props {/*the-problem-with-passing-props*/} +## Masalah ketika mengoper props {/*the-problem-with-passing-props*/} -[Passing props](/learn/passing-props-to-a-component) is a great way to explicitly pipe data through your UI tree to the components that use it. +[Mengoper *props*](/learn/passing-props-to-a-component) adalah cara yang bagus untuk menyalurkan data secara eksplisit melalui pohon UI Anda ke komponen yang menggunakanya. -But passing props can become verbose and inconvenient when you need to pass some prop deeply through the tree, or if many components need the same prop. The nearest common ancestor could be far removed from the components that need data, and [lifting state up](/learn/sharing-state-between-components) that high can lead to a situation called "prop drilling". +Tapi mengoper *props* bisa menjadi bertele-tele dan tidak nyaman ketika Anda perlu mengoper beberapa *prop* secara mendalam melalui pohon, atau jika banyak komponen membutuhkan *prop* yang sama. Leluhur umum terdekat bisa jadi jauh dari komponen yang membutuhkan data, dan [memindahkan state ke atas](/learn/sharing-state-between-components) dapat menyebabkan yang disebut "*prop drilling*". -Lifting state up +Memindahkan state ke atas @@ -38,11 +38,11 @@ Prop drilling -Wouldn't it be great if there were a way to "teleport" data to the components in the tree that need it without passing props? With React's context feature, there is! +Bukankah lebih bagus jika ada cara untuk "memindahkan" data ke komponen di dalam pohon yang membutuhkannya tanpa harus mengoper *props*? Dengan fitur *context* React, ternyata ada! -## Context: an alternative to passing props {/*context-an-alternative-to-passing-props*/} +## *Context*: sebuah alternatif untuk mengoper *props* {/*context-an-alternative-to-passing-props*/} -Context lets a parent component provide data to the entire tree below it. There are many uses for context. Here is one example. Consider this `Heading` component that accepts a `level` for its size: +*Context* memungkinkan sebuah komponen induk menyediakan data untuk seluruh pohon di bawahnya. Ada banyak kegunaan dari *context*. Berikut ini salah satu contohnya. Perhatikan komponen `Heading` ini yang menerima `level` untuk ukurannya: @@ -53,7 +53,7 @@ import Section from './Section.js'; export default function Page() { return (
- Title + Judul Heading Sub-heading Sub-sub-heading @@ -106,7 +106,7 @@ export default function Heading({ level, children }) { -Let's say you want multiple headings within the same `Section` to always have the same size: +Katakanlah Anda ingin beberapa judul dalam `Section` yang sama selalu memiliki ukuran yang sama: @@ -180,7 +180,7 @@ export default function Heading({ level, children }) { -Currently, you pass the `level` prop to each `` separately: +Saat ini, Anda mengoper `level` *props* ke tiap `` secara terpisah: ```js
@@ -190,7 +190,7 @@ Currently, you pass the `level` prop to each `` separately:
``` -It would be nice if you could pass the `level` prop to the `
` component instead and remove it from the ``. This way you could enforce that all headings in the same section have the same size: +Akan lebih baik jika Anda dapat mengoper *prop* `level` ke komponen `
` dan menghapusnya dari komponen `` Dengan cara ini Anda dapat menerapkan bahwa semua judul di bagian yang sama memiliki ukuran yang sama: ```js
@@ -200,35 +200,35 @@ It would be nice if you could pass the `level` prop to the `
` component
``` -But how can the `` component know the level of its closest `
`? **That would require some way for a child to "ask" for data from somewhere above in the tree.** +Tapi bagaimana komponen `` dapat mengetahui level `
` yang terdekat? **Hal ini akan membutuhkan suatu cara untuk "meminta" data dari suatu tempat di atas pohon.** -You can't do it with props alone. This is where context comes into play. You will do it in three steps: +Anda tidak bisa melakukannya dengan *props* sendirian. Di sinilah *context* berperan penting. Anda akan melakukannya dalam tiga langkah: -1. **Create** a context. (You can call it `LevelContext`, since it's for the heading level.) -2. **Use** that context from the component that needs the data. (`Heading` will use `LevelContext`.) -3. **Provide** that context from the component that specifies the data. (`Section` will provide `LevelContext`.) +1. **Buat** sebuah *context*. (Anda dapat menamainya `LevelContext`, karena ini untuk level judul.) +2. **Gunakan** *context* tersebut dari komponen yang membutuhkan data. (`Heading` akan menggunakan `LevelContext`.) +3. **Sediakan** *context* tersebut dari komponen yang menentukan data. (`Section` akan menyediakan `LevelContext`.) -Context lets a parent--even a distant one!--provide some data to the entire tree inside of it. +*Context* memungkinkan sebuah induk--bahkan yang jauh sekalipun!--menyediakan beberapa data kepada seluruh komponen pohon di dalamnya. -Using context in close children +Menggunakan *context* di *children* terdekat -Using context in distant children +Menggunakan *context* di *children* yang jauh -### Step 1: Create the context {/*step-1-create-the-context*/} +### Langkah 1: Buat *context* {/*step-1-create-the-context*/} -First, you need to create the context. You'll need to **export it from a file** so that your components can use it: +Pertama, Anda perlu membuat *context*. Anda harus **mengekspornya dari sebuah file** sehingga komponen Anda dapat menggunakannya: @@ -239,7 +239,7 @@ import Section from './Section.js'; export default function Page() { return (
- Title + Judul
Heading Heading @@ -308,18 +308,18 @@ export const LevelContext = createContext(1); -The only argument to `createContext` is the _default_ value. Here, `1` refers to the biggest heading level, but you could pass any kind of value (even an object). You will see the significance of the default value in the next step. +Satu-satunya argumen untuk `createContext` adalah nilai *default*. Disini, `1` merujuk pada level *heading* terbesar, tapi Anda dapat mengoper nilai apa pun (bahkan sebuah objek). Anda akan melihat pentingnya nilai *default* di langkah selanjutnya. -### Step 2: Use the context {/*step-2-use-the-context*/} +### Langkah 2: Gunakan *context* {/*step-2-use-the-context*/} -Import the `useContext` Hook from React and your context: +Impor `useContext` *Hook* dari React dan *context* Anda: ```js import { useContext } from 'react'; import { LevelContext } from './LevelContext.js'; ``` -Currently, the `Heading` component reads `level` from props: +Saat ini, komponen `Heading` membaca `level` dari *props*: ```js export default function Heading({ level, children }) { @@ -327,7 +327,7 @@ export default function Heading({ level, children }) { } ``` -Instead, remove the `level` prop and read the value from the context you just imported, `LevelContext`: +Sebagai gantinya, hapus *prop* `level` dan baca nilai dari *context* yang baru saja Anda impor, `LevelContext`: ```js {2} export default function Heading({ children }) { @@ -336,9 +336,9 @@ export default function Heading({ children }) { } ``` -`useContext` is a Hook. Just like `useState` and `useReducer`, you can only call a Hook immediately inside a React component (not inside loops or conditions). **`useContext` tells React that the `Heading` component wants to read the `LevelContext`.** +`useContext` adalah sebuah *Hook*. Sama seperti `useState` dan `useReducer`, Anda hanya dapat memanggil sebuah *Hook* secara langsung di dalam komponen React (bukan di dalam pengulangan atau pengkondisian). **`useContext` memberitahu React bahwa komponen `Heading` mau membaca `LevelContext`.** -Now that the `Heading` component doesn't have a `level` prop, you don't need to pass the level prop to `Heading` in your JSX like this anymore: +Sekarang komponen `Heading` tidak membutuhkan sebuah prop `level`, Anda tidak perlu mengoper level *prop* ke `Heading` di JSX Anda seperti ini lagi: ```js
@@ -348,7 +348,7 @@ Now that the `Heading` component doesn't have a `level` prop, you don't need to
``` -Update the JSX so that it's the `Section` that receives it instead: +Sebagai gantinya Perbarui JSX sehingga `Section` yang dapat menerimanya: ```jsx
@@ -358,7 +358,7 @@ Update the JSX so that it's the `Section` that receives it instead:
``` -As a reminder, this is the markup that you were trying to get working: +Sebagai pengingat, ini adalah markup yang sedang Anda coba untuk bekerja: @@ -369,7 +369,7 @@ import Section from './Section.js'; export default function Page() { return (
- Title + Judul
Heading Heading @@ -442,13 +442,13 @@ export const LevelContext = createContext(1); -Notice this example doesn't quite work, yet! All the headings have the same size because **even though you're *using* the context, you have not *provided* it yet.** React doesn't know where to get it! +Perhatikan contoh ini masih belum berfungsi dengan baik! Semua judul memiliki ukuran yang sama karena **meskipun Anda *menggunakan* *context*, Anda belum *menyediakannya*.** React tidak tahu darimana untuk mendapatkannya! -If you don't provide the context, React will use the default value you've specified in the previous step. In this example, you specified `1` as the argument to `createContext`, so `useContext(LevelContext)` returns `1`, setting all those headings to `

`. Let's fix this problem by having each `Section` provide its own context. +Jika Anda tidak menyediakan *context*, React akan menggunakan nilai *default* yang sudah Anda tentukan di langkah sebelumnya. Di contoh ini, Anda menentukan `1` sebagai argumen `createContext`, jadi `useContext(LevelContext)` mengembalikan `1`, mengatur semua *headings* ke `

`. Ayo kita perbaiki masalah ini dengan membuat setiap `Section` menyediakan *context*-nya sendiri. -### Step 3: Provide the context {/*step-3-provide-the-context*/} +### Langkah 3: Sediakan *context* {/*step-3-provide-the-context*/} -The `Section` component currently renders its children: +Komponen `Section` saat ini me*renders* anaknya: ```js export default function Section({ children }) { @@ -460,7 +460,7 @@ export default function Section({ children }) { } ``` -**Wrap them with a context provider** to provide the `LevelContext` to them: +**Bungkus mereka semua dengan sebuah _context provider_** untuk menyediakan `LevelContext` kepada mereka: ```js {1,6,8} import { LevelContext } from './LevelContext.js'; @@ -476,7 +476,7 @@ export default function Section({ level, children }) { } ``` -This tells React: "if any component inside this `
` asks for `LevelContext`, give them this `level`." The component will use the value of the nearest `` in the UI tree above it. +Ini memberitahu React: "jika ada komponen di dalam `
` ini yang meminta `LevelContext`, berikan `level` ini." Komponen akan menggunakan nilai dari `` terdekat di pohon UI tree di atasnya. @@ -487,7 +487,7 @@ import Section from './Section.js'; export default function Page() { return (
- Title + Judul
Heading Heading @@ -564,15 +564,15 @@ export const LevelContext = createContext(1); -It's the same result as the original code, but you did not need to pass the `level` prop to each `Heading` component! Instead, it "figures out" its heading level by asking the closest `Section` above: +Hasilnya sama dengan kode aslinya, tapi Anda tidak perlu mengoper *prop* `level` ke setiap komponen `Heading`! Sebagai gantinya, ia "mencari tahu" *level heading*-nya dengan meminta `Section` terdekat di atasnya: -1. You pass a `level` prop to the `
`. -2. `Section` wraps its children into ``. -3. `Heading` asks the closest value of `LevelContext` above with `useContext(LevelContext)`. +1. Anda mengoper *prop* `level` ke `
`. +2. `Section` membungkus anaknya dengan ``. +3. `Heading` meminta nilai terdekat dari `LevelContext` di atasnya dengan `useContext(LevelContext)`. -## Using and providing context from the same component {/*using-and-providing-context-from-the-same-component*/} +## Menggunakan dan menyediakan *context* dari komponen yang sama {/*using-and-providing-context-from-the-same-component*/} -Currently, you still have to specify each section's `level` manually: +Saat ini, Anda masih harus menentukan setiap `level` *section's* secara manual: ```js export default function Page() { @@ -585,7 +585,7 @@ export default function Page() { ... ``` -Since context lets you read information from a component above, each `Section` could read the `level` from the `Section` above, and pass `level + 1` down automatically. Here is how you could do it: +Karena *context* memungkinan Anda membaca informasi dari komponen di atasnya, setiap `Section` dapat membaca `level` dari `Section` di atasnya, dan mengoper `level + 1` ke bawah secara otomatis. Berikut adalah bagaimana Anda dapat melakukannya: ```js Section.js {5,8} import { useContext } from 'react'; @@ -603,7 +603,7 @@ export default function Section({ children }) { } ``` -With this change, you don't need to pass the `level` prop *either* to the `
` or to the ``: +Dengan perubahan ini, Anda tidak perlu mengoper *prop* `level` baik ke `
` atau ke ``: @@ -614,7 +614,7 @@ import Section from './Section.js'; export default function Page() { return (
- Title + Judul
Heading Heading @@ -695,19 +695,19 @@ export const LevelContext = createContext(0); -Now both `Heading` and `Section` read the `LevelContext` to figure out how "deep" they are. And the `Section` wraps its children into the `LevelContext` to specify that anything inside of it is at a "deeper" level. +Sekarang keduanya `Heading` dan `Section` membaca `LevelContext` untuk mencari tahu seberapa "dalam" mereka. Dan `Section` membungkus anaknya ke dalam `LevelContext` untuk menentukan bahwa apa pun yang ada di dalamnya berada pada *level* yang "lebih dalam". -This example uses heading levels because they show visually how nested components can override context. But context is useful for many other use cases too. You can pass down any information needed by the entire subtree: the current color theme, the currently logged in user, and so on. +Contoh ini menggunakan *heading levels* karena mereka menunjukkan secara visual bagaimana komponen bersarang dapat menimpa *context*. Tapi *context* juga berguna untuk banyak kasus penggunaan lainnya. Anda dapat mengoper ke bawah informasi apa pun yang dibutuhkan oleh seluruh *sub*-pohon: tema warna saat ini, pengguna yang sedang masuk, dan seterusnya. -## Context passes through intermediate components {/*context-passes-through-intermediate-components*/} +## *Context* melewati komponen perantara {/*context-passes-through-intermediate-components*/} -You can insert as many components as you like between the component that provides context and the one that uses it. This includes both built-in components like `
` and components you might build yourself. +Anda dapat menyisipkan sebanyak mungkin komponen di antara komponen yang menyediakan *context* dan komponen yang menggunakannya. Ini termasuk komponen bawaan seperti `
` dan komponen yang mungkin Anda buat sendiri. -In this example, the same `Post` component (with a dashed border) is rendered at two different nesting levels. Notice that the `` inside of it gets its level automatically from the closest `
`: +Di contoh berikut, komponen `Post` yang sama (dengan batas putus-putus) diberikan pada dua tingkat sarang yang berbeda. Perhatikan bahwa `` di dalamnya mendapatkan *level*-nya secara otomatis dari `
` terdekat: @@ -718,10 +718,10 @@ import Section from './Section.js'; export default function ProfilePage() { return (
- My Profile + Profil Saya
@@ -740,14 +740,14 @@ function AllPosts() { function RecentPosts() { return (
- Recent Posts + Posting Terbaru
); @@ -832,58 +832,58 @@ export const LevelContext = createContext(0);
-You didn't do anything special for this to work. A `Section` specifies the context for the tree inside it, so you can insert a `` anywhere, and it will have the correct size. Try it in the sandbox above! +Anda tidak perlu melakukan sesuatu yang khusus untuk pekerjaan ini. `Section` menentukan *context* untuk pohon di dalamnya, jadi Anda dapat menyisipkan `` di mana saja, dan akan memiliki ukuran yang benar. Cobalah di kotak pasir di atas! -**Context lets you write components that "adapt to their surroundings" and display themselves differently depending on _where_ (or, in other words, _in which context_) they are being rendered.** +**_Context_ memungkinkan Anda untuk menulis komponen yang "beradaptasi dengan sekitar mereka" dan menampilkan diri mereka secara berbeda tergantung di mana (atau, dalam kata lain, _dalam context apa_) mereka akan diberikan.** -How context works might remind you of [CSS property inheritance.](https://developer.mozilla.org/en-US/docs/Web/CSS/inheritance) In CSS, you can specify `color: blue` for a `
`, and any DOM node inside of it, no matter how deep, will inherit that color unless some other DOM node in the middle overrides it with `color: green`. Similarly, in React, the only way to override some context coming from above is to wrap children into a context provider with a different value. +Cara kerja *context* mungkin mengingatkan Anda pada [pewarisan properti CSS.](https://developer.mozilla.org/en-US/docs/Web/CSS/inheritance) Pada CSS, Anda dapat menentukan `color: blue` untuk `
`, dan simpul DOM apa pun di dalamnya, tidak peduli seberapa dalam, akan mewarisi warna tersebut kecuali ada simpul DOM lain di tengahnya yang menimpanya dengan `color: green`. Demikian pula, dalam React, satu-satunya cara untuk menimpa beberapa *context* yang bersal dari atas adalah dengan membungkus anaknya ke dalam penyedia *context* dengan nilai yang berbeda. -In CSS, different properties like `color` and `background-color` don't override each other. You can set all `
`'s `color` to red without impacting `background-color`. Similarly, **different React contexts don't override each other.** Each context that you make with `createContext()` is completely separate from other ones, and ties together components using and providing *that particular* context. One component may use or provide many different contexts without a problem. +Pada CSS, properti berbeda seperti `color` dan `background-color` tidak akan menimpa satu sama lain. Anda dapat mengatur semua `color` `
` ke merah tanpa berdampak pada `background-color`. Demikian pula, **React contexts yang berbeda tidak akan menimpa satu sama lain.** Tiap *context* yang Anda buat dengan `createContext()` benar-benar terpisah dari yang lain, dan menyatukan komponen-komponen yang menggunakan dan menyediakan context *tertentu*. Satu komponen dapat menggunakan atau menyediakan banyak konteks yang berbeda tanpa masalah. -## Before you use context {/*before-you-use-context*/} +## Sebelum Anda menggunakan *context* {/*before-you-use-context*/} -Context is very tempting to use! However, this also means it's too easy to overuse it. **Just because you need to pass some props several levels deep doesn't mean you should put that information into context.** +*Context* sangat menggoda untuk digunakan! Namun, ini juga terlalu mudah untuk menggunakannya secara berlebihan. **Hanya karena Anda membutuhkan untuk mengoper beberapa _props_ beberapa tingkat lebih dalam bukan berarti Anda memasukkan informasi tersebut ke dalam _context_.** -Here's a few alternatives you should consider before using context: +Ini adalah beberapa alternatif yang harus Anda pertimbangkan sebelum menggunakan *context*: -1. **Start by [passing props.](/learn/passing-props-to-a-component)** If your components are not trivial, it's not unusual to pass a dozen props down through a dozen components. It may feel like a slog, but it makes it very clear which components use which data! The person maintaining your code will be glad you've made the data flow explicit with props. -2. **Extract components and [pass JSX as `children`](/learn/passing-props-to-a-component#passing-jsx-as-children) to them.** If you pass some data through many layers of intermediate components that don't use that data (and only pass it further down), this often means that you forgot to extract some components along the way. For example, maybe you pass data props like `posts` to visual components that don't use them directly, like ``. Instead, make `Layout` take `children` as a prop, and render ``. This reduces the number of layers between the component specifying the data and the one that needs it. +1. **Mulai dengan [mengoper *props*.](/learn/passing-props-to-a-component)** Jika komponen Anda tidak sepele, bukan hal yang aneh jika Anda mengoper selusin *props* melalui selusin komponen. Ini mungkin terasa seperti pekerjaan berat, tapi membuatnya sangat jelas komponen yang mana menggunakan data yang mana! Orang yang mengelola kode Anda akan senang Anda telah membuat aliran data eksplisit dengan *props*. +2. **Ekstrak komponen dan [oper JSX sebagai `children`](/learn/passing-props-to-a-component#passing-jsx-as-children) ke mereka.** Jika Anda mengoper beberapa data melewati banyak lapisan komponen perantara yang tidak menggunakan data tersebut (dan hanya mengopernya lebih jauh ke bawah), ini sering kali Anda lupa mengekstrak beberapa komponen di sepanjang jalan. Contohnya, mungkin Anda mengoper data *props* seperti `posts` ke komponen visual yang tidak menggunakannya secara langsung, seperti ``. Sebagai gantinya, buat `Layout` mengambil `children` sebagai *prop*, dan berikan ``. Hal ini mengurangi jumlah lapisan antara komponen yang menentukan data dan komponen yang membutuhkannya. -If neither of these approaches works well for you, consider context. +Jika tidak satu pun dari pendekatan ini yang cocok untuk Anda, pertimbangkan *context*. -## Use cases for context {/*use-cases-for-context*/} +## Kasus penggunakan untuk *context* {/*use-cases-for-context*/} -* **Theming:** If your app lets the user change its appearance (e.g. dark mode), you can put a context provider at the top of your app, and use that context in components that need to adjust their visual look. -* **Current account:** Many components might need to know the currently logged in user. Putting it in context makes it convenient to read it anywhere in the tree. Some apps also let you operate multiple accounts at the same time (e.g. to leave a comment as a different user). In those cases, it can be convenient to wrap a part of the UI into a nested provider with a different current account value. -* **Routing:** Most routing solutions use context internally to hold the current route. This is how every link "knows" whether it's active or not. If you build your own router, you might want to do it too. -* **Managing state:** As your app grows, you might end up with a lot of state closer to the top of your app. Many distant components below may want to change it. It is common to [use a reducer together with context](/learn/scaling-up-with-reducer-and-context) to manage complex state and pass it down to distant components without too much hassle. +* **Tema:** Jika aplikasi Anda memungkinkan pengguna mengganti penampilannya (misalnya mode gelap), Anda dapat menempatkan penyedia *context* di paling atas aplikasi Anda, dan menggunakan konteksnya di komponen yang membutuhkan untuk menyesuaikan tampilan visual mereka. +* **Akun saat ini:** Banyak komponen yang mungkin perlu mengetahui pengguna yang sedang masuk. Menempatkannya dalam konteks akan memudahkan untuk membacanya di mana saja di dalam pohon. Beberapa aplikasi memungkinkan Anda mengoperasikan beberapa akun pada saat yang sama (misalnya untuk memberikan komentar sebagai pengguna yang berbeda). Dalam kasus tersebut, akan lebih mudah untuk membungkus bagian dari UI ke dalam penyedia bersarang dengan nilai akun saat ini yang berbeda. +* **Routing:** Sebagian besar solusi *routing* menggunakan *context* secara internal untuk menyimpan rute saat ini. Dengan cara inilah setiap link "mengetahui" apakah ia aktif atau tidak. Jika Anda membuat *router* anda sendiri, Anda mungkin ingin melakukannya juga. +* **Mengelola state:** Seiring pertumbuhan aplikasi Anda, Anda mungkin akan menempatkan banyak *state* yang lebih dekat ke bagian atas aplikasi Anda. Nanyak komponen yang jauh di bawahnya mungkin ingin untuk mengubahnya. Ini adalah hal yang umum untuk [menggunakan reducer bersama dengan *context*](/learn/scaling-up-with-reducer-and-context) untuk mengelola *state* yang kompleks dan mengopernya ke komponen yang jauh ke bawah tanpa terlalu banyak kerumitan. -Context is not limited to static values. If you pass a different value on the next render, React will update all the components reading it below! This is why context is often used in combination with state. +*Context* tidak terbatas pada nilai statis. Jika anda memberikan nilai yang berbeda pada render berikutnya, React akan memperbarui semua komponen yang membacanya di bawahnya! Inilah sebabnya mengapa *context* sering digunakan bersama degan *state*. -In general, if some information is needed by distant components in different parts of the tree, it's a good indication that context will help you. +Pada umumnya, jika beberapa informasi dibutuhkan oleh komponen yang jauh di beberapa bagian pohon, ini adalah indikasi yang bagus bahwa *context* akan membantu Anda. -* Context lets a component provide some information to the entire tree below it. -* To pass context: - 1. Create and export it with `export const MyContext = createContext(defaultValue)`. - 2. Pass it to the `useContext(MyContext)` Hook to read it in any child component, no matter how deep. - 3. Wrap children into `` to provide it from a parent. -* Context passes through any components in the middle. -* Context lets you write components that "adapt to their surroundings". -* Before you use context, try passing props or passing JSX as `children`. +* *Context* memungkinkan komponen menyediakan beberapa informasi ke keseluruhan pohon di bawahnya. +* Untuk mengoper *context*: + 1. Buat dan ekspor ia dengan `export const MyContext = createContext(defaultValue)`. + 2. Oper ke `useContext(MyContext)` *Hook* untuk membacanya di komponen anak manapun, tidak peduli seberapa dalam. + 3. Bungkus anak ke `` untuk menyediakannya dari induk. +* *Context* melewati komponen apa pun di tengahnya. +* *Context* memungkinkan Anda menulis komponen yang "beradaptasi dengan sekitar mereke". +* Sebelum Anda menggunakan *context*, coba oper *props* atau oper JSX sebagai `children`. -#### Replace prop drilling with context {/*replace-prop-drilling-with-context*/} +#### Ganti *prop drilling* dengan *context* {/*replace-prop-drilling-with-context*/} -In this example, toggling the checkbox changes the `imageSize` prop passed to each ``. The checkbox state is held in the top-level `App` component, but each `` needs to be aware of it. +Pada contoh ini, mengganti checkbox akan mengubah `imageSize` *prop* yang diteruskan ke setiap ``. checkbox state akan disimpan di komponen paling atas komponen `App`, tapi tiap `` harus menyadarinya. -Currently, `App` passes `imageSize` to `List`, which passes it to each `Place`, which passes it to the `PlaceImage`. Remove the `imageSize` prop, and instead pass it from the `App` component directly to `PlaceImage`. +Saat ini, `App` mengoper `imageSize` ke `List`, yang mana mengopernya ke tiap `Place`, yang mana mengopernya ke tiap `PlaceImage`. Hapus *prop* `imageSize`, dan sebagai gantinya oper ia dari komponen `App` ke `PlaceImage` secara langsung. -You can declare context in `Context.js`. +Anda dapat deklarasi *context* di `Context.js`. @@ -905,7 +905,7 @@ export default function App() { setIsLarge(e.target.checked); }} /> - Use large images + Menggunakan gambar besar
@@ -959,38 +959,38 @@ function PlaceImage({ place, imageSize }) { ```js data.js export const places = [{ id: 0, - name: 'Bo-Kaap in Cape Town, South Africa', - description: 'The tradition of choosing bright colors for houses began in the late 20th century.', + name: 'Bo-Kaap di Cape Town, Afrika Selatan', + description: 'Tradisi memilih warna-warna cerah untuk rumah dimulai pada akhir abad ke-20.', imageId: 'K9HVAGH' }, { id: 1, - name: 'Rainbow Village in Taichung, Taiwan', - description: 'To save the houses from demolition, Huang Yung-Fu, a local resident, painted all 1,200 of them in 1924.', + name: 'Desa Pelangi di Taichung, Taiwan', + description: 'Untuk menyelamatkan rumah-rumah tersebut dari pembongkaran, Huang Yung-Fu, seorang penduduk setempat, mengecat 1.200 rumah tersebut pada tahun 1924.', imageId: '9EAYZrt' }, { id: 2, - name: 'Macromural de Pachuca, Mexico', - description: 'One of the largest murals in the world covering homes in a hillside neighborhood.', + name: 'Macromural de Pachuca, Meksiko', + description: 'Salah satu mural terbesar di dunia yang menutupi rumah-rumah di lingkungan lereng bukit.', imageId: 'DgXHVwu' }, { id: 3, - name: 'Selarón Staircase in Rio de Janeiro, Brazil', - description: 'This landmark was created by Jorge Selarón, a Chilean-born artist, as a "tribute to the Brazilian people."', + name: 'Selarón Staircase di Rio de Janeiro, Brasil', + description: 'Tengara ini diciptakan oleh Jorge Selarón, seorang seniman kelahiran Chili, sebagai "penghormatan kepada rakyat Brasil."', imageId: 'aeO3rpI' }, { id: 4, name: 'Burano, Italy', - description: 'The houses are painted following a specific color system dating back to 16th century.', + description: 'Rumah-rumahnya dicat mengikuti sistem warna tertentu yang berasal dari abad ke-16.', imageId: 'kxsph5C' }, { id: 5, - name: 'Chefchaouen, Marocco', - description: 'There are a few theories on why the houses are painted blue, including that the color repells mosquitos or that it symbolizes sky and heaven.', + name: 'Chefchaouen, Maroko', + description: 'Ada beberapa teori mengapa rumah-rumah dicat biru, termasuk bahwa warna tersebut dapat mengusir nyamuk atau melambangkan langit dan surga.', imageId: 'rTqKo46' }, { id: 6, - name: 'Gamcheon Culture Village in Busan, South Korea', - description: 'In 2009, the village was converted into a cultural hub by painting the houses and featuring exhibitions and art installations.', + name: 'Desa Budaya Gamcheon di Busan, Korea Selatan', + description: 'Pada tahun 2009, desa ini diubah menjadi pusat budaya dengan mengecat rumah-rumah dan menampilkan pameran dan instalasi seni.', imageId: 'ZfQOOzf' }]; ``` @@ -1020,9 +1020,9 @@ li { -Remove `imageSize` prop from all the components. +Hapus prop `imageSize` dari semua komponen. -Create and export `ImageSizeContext` from `Context.js`. Then wrap the List into `` to pass the value down, and `useContext(ImageSizeContext)` to read it in the `PlaceImage`: +Buat dan ekspor `ImageSizeContext` dari `Context.js`. Lalu bungkus List ke `` untuk mengoper nilai ke bawah, dan `useContext(ImageSizeContext)` untuk membacanya di `PlaceImage`: @@ -1047,7 +1047,7 @@ export default function App() { setIsLarge(e.target.checked); }} /> - Use large images + Menggunakan gambar besar
@@ -1098,38 +1098,38 @@ export const ImageSizeContext = createContext(500); ```js data.js export const places = [{ id: 0, - name: 'Bo-Kaap in Cape Town, South Africa', - description: 'The tradition of choosing bright colors for houses began in the late 20th century.', + name: 'Bo-Kaap di Cape Town, Afrika Selatan', + description: 'Tradisi memilih warna-warna cerah untuk rumah dimulai pada akhir abad ke-20.', imageId: 'K9HVAGH' }, { id: 1, - name: 'Rainbow Village in Taichung, Taiwan', - description: 'To save the houses from demolition, Huang Yung-Fu, a local resident, painted all 1,200 of them in 1924.', + name: 'Desa Pelangi di Taichung, Taiwan', + description: 'Untuk menyelamatkan rumah-rumah tersebut dari pembongkaran, Huang Yung-Fu, seorang penduduk setempat, mengecat 1.200 rumah tersebut pada tahun 1924.', imageId: '9EAYZrt' }, { id: 2, - name: 'Macromural de Pachuca, Mexico', - description: 'One of the largest murals in the world covering homes in a hillside neighborhood.', + name: 'Macromural de Pachuca, Meksiko', + description: 'Salah satu mural terbesar di dunia yang menutupi rumah-rumah di lingkungan lereng bukit.', imageId: 'DgXHVwu' }, { id: 3, - name: 'Selarón Staircase in Rio de Janeiro, Brazil', - description: 'This landmark was created by Jorge Selarón, a Chilean-born artist, as a "tribute to the Brazilian people".', + name: 'Selarón Staircase di Rio de Janeiro, Brasil', + description: 'Tengara ini diciptakan oleh Jorge Selarón, seorang seniman kelahiran Chili, sebagai "penghormatan kepada rakyat Brasil."', imageId: 'aeO3rpI' }, { id: 4, name: 'Burano, Italy', - description: 'The houses are painted following a specific color system dating back to 16th century.', + description: 'Rumah-rumahnya dicat mengikuti sistem warna tertentu yang berasal dari abad ke-16.', imageId: 'kxsph5C' }, { id: 5, - name: 'Chefchaouen, Marocco', - description: 'There are a few theories on why the houses are painted blue, including that the color repells mosquitos or that it symbolizes sky and heaven.', + name: 'Chefchaouen, Maroko', + description: 'Ada beberapa teori mengapa rumah-rumah dicat biru, termasuk bahwa warna tersebut dapat mengusir nyamuk atau melambangkan langit dan surga.', imageId: 'rTqKo46' }, { id: 6, - name: 'Gamcheon Culture Village in Busan, South Korea', - description: 'In 2009, the village was converted into a cultural hub by painting the houses and featuring exhibitions and art installations.', + name: 'Desa Budaya Gamcheon di Busan, Korea Selatan', + description: 'Pada tahun 2009, desa ini diubah menjadi pusat budaya dengan mengecat rumah-rumah dan menampilkan pameran dan instalasi seni.', imageId: 'ZfQOOzf' }]; ``` @@ -1157,7 +1157,7 @@ li {
-Note how components in the middle don't need to pass `imageSize` anymore. +Perhatikan bagaimana komponen di tengah tidak perlu lagi mengoper `imageSize`.
From 3db5f3f35c7d34722212903d7a0280ef4474a0cb Mon Sep 17 00:00:00 2001 From: Muhammad Ridwan Date: Tue, 2 May 2023 18:25:31 +0700 Subject: [PATCH 2/5] docs: fix some typo in passing data deeply with context --- src/content/learn/passing-data-deeply-with-context.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index 31eacc8ff..4324915b7 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -836,7 +836,7 @@ Anda tidak perlu melakukan sesuatu yang khusus untuk pekerjaan ini. `Section` me **_Context_ memungkinkan Anda untuk menulis komponen yang "beradaptasi dengan sekitar mereka" dan menampilkan diri mereka secara berbeda tergantung di mana (atau, dalam kata lain, _dalam context apa_) mereka akan diberikan.** -Cara kerja *context* mungkin mengingatkan Anda pada [pewarisan properti CSS.](https://developer.mozilla.org/en-US/docs/Web/CSS/inheritance) Pada CSS, Anda dapat menentukan `color: blue` untuk `
`, dan simpul DOM apa pun di dalamnya, tidak peduli seberapa dalam, akan mewarisi warna tersebut kecuali ada simpul DOM lain di tengahnya yang menimpanya dengan `color: green`. Demikian pula, dalam React, satu-satunya cara untuk menimpa beberapa *context* yang bersal dari atas adalah dengan membungkus anaknya ke dalam penyedia *context* dengan nilai yang berbeda. +Cara kerja *context* mungkin mengingatkan Anda pada [pewarisan properti CSS.](https://developer.mozilla.org/en-US/docs/Web/CSS/inheritance) Pada CSS, Anda dapat menentukan `color: blue` untuk `
`, dan simpul DOM apa pun di dalamnya, tidak peduli seberapa dalam, akan mewarisi warna tersebut kecuali ada simpul DOM lain di tengahnya yang menimpanya dengan `color: green`. Demikian pula, dalam React, satu-satunya cara untuk menimpa beberapa *context* yang berasal dari atas adalah dengan membungkus anaknya ke dalam penyedia *context* dengan nilai yang berbeda. Pada CSS, properti berbeda seperti `color` dan `background-color` tidak akan menimpa satu sama lain. Anda dapat mengatur semua `color` `
` ke merah tanpa berdampak pada `background-color`. Demikian pula, **React contexts yang berbeda tidak akan menimpa satu sama lain.** Tiap *context* yang Anda buat dengan `createContext()` benar-benar terpisah dari yang lain, dan menyatukan komponen-komponen yang menggunakan dan menyediakan context *tertentu*. Satu komponen dapat menggunakan atau menyediakan banyak konteks yang berbeda tanpa masalah. @@ -856,7 +856,7 @@ Jika tidak satu pun dari pendekatan ini yang cocok untuk Anda, pertimbangkan *co * **Tema:** Jika aplikasi Anda memungkinkan pengguna mengganti penampilannya (misalnya mode gelap), Anda dapat menempatkan penyedia *context* di paling atas aplikasi Anda, dan menggunakan konteksnya di komponen yang membutuhkan untuk menyesuaikan tampilan visual mereka. * **Akun saat ini:** Banyak komponen yang mungkin perlu mengetahui pengguna yang sedang masuk. Menempatkannya dalam konteks akan memudahkan untuk membacanya di mana saja di dalam pohon. Beberapa aplikasi memungkinkan Anda mengoperasikan beberapa akun pada saat yang sama (misalnya untuk memberikan komentar sebagai pengguna yang berbeda). Dalam kasus tersebut, akan lebih mudah untuk membungkus bagian dari UI ke dalam penyedia bersarang dengan nilai akun saat ini yang berbeda. * **Routing:** Sebagian besar solusi *routing* menggunakan *context* secara internal untuk menyimpan rute saat ini. Dengan cara inilah setiap link "mengetahui" apakah ia aktif atau tidak. Jika Anda membuat *router* anda sendiri, Anda mungkin ingin melakukannya juga. -* **Mengelola state:** Seiring pertumbuhan aplikasi Anda, Anda mungkin akan menempatkan banyak *state* yang lebih dekat ke bagian atas aplikasi Anda. Nanyak komponen yang jauh di bawahnya mungkin ingin untuk mengubahnya. Ini adalah hal yang umum untuk [menggunakan reducer bersama dengan *context*](/learn/scaling-up-with-reducer-and-context) untuk mengelola *state* yang kompleks dan mengopernya ke komponen yang jauh ke bawah tanpa terlalu banyak kerumitan. +* **Mengelola state:** Seiring pertumbuhan aplikasi Anda, Anda mungkin akan menempatkan banyak *state* yang lebih dekat ke bagian atas aplikasi Anda. Banyak komponen yang jauh di bawahnya mungkin ingin untuk mengubahnya. Ini adalah hal yang umum untuk [menggunakan reducer bersama dengan *context*](/learn/scaling-up-with-reducer-and-context) untuk mengelola *state* yang kompleks dan mengopernya ke komponen yang jauh ke bawah tanpa terlalu banyak kerumitan. *Context* tidak terbatas pada nilai statis. Jika anda memberikan nilai yang berbeda pada render berikutnya, React akan memperbarui semua komponen yang membacanya di bawahnya! Inilah sebabnya mengapa *context* sering digunakan bersama degan *state*. From b9d01817c5088aa35a9a2ca78dd8a5ccb6bbc606 Mon Sep 17 00:00:00 2001 From: Muhammad Ridwan Date: Tue, 2 May 2023 18:31:29 +0700 Subject: [PATCH 3/5] docs: fix word `state` to italic --- src/content/learn/passing-data-deeply-with-context.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index 4324915b7..bb8ac006e 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -21,13 +21,13 @@ Biasanya, Anda akan mengoper informasi dari komponen induk ke komponen anak mela [Mengoper *props*](/learn/passing-props-to-a-component) adalah cara yang bagus untuk menyalurkan data secara eksplisit melalui pohon UI Anda ke komponen yang menggunakanya. -Tapi mengoper *props* bisa menjadi bertele-tele dan tidak nyaman ketika Anda perlu mengoper beberapa *prop* secara mendalam melalui pohon, atau jika banyak komponen membutuhkan *prop* yang sama. Leluhur umum terdekat bisa jadi jauh dari komponen yang membutuhkan data, dan [memindahkan state ke atas](/learn/sharing-state-between-components) dapat menyebabkan yang disebut "*prop drilling*". +Tapi mengoper *props* bisa menjadi bertele-tele dan tidak nyaman ketika Anda perlu mengoper beberapa *prop* secara mendalam melalui pohon, atau jika banyak komponen membutuhkan *prop* yang sama. Leluhur umum terdekat bisa jadi jauh dari komponen yang membutuhkan data, dan [memindahkan *state* ke atas](/learn/sharing-state-between-components) dapat menyebabkan yang disebut "*prop drilling*". -Memindahkan state ke atas +Memindahkan *state* ke atas @@ -856,7 +856,7 @@ Jika tidak satu pun dari pendekatan ini yang cocok untuk Anda, pertimbangkan *co * **Tema:** Jika aplikasi Anda memungkinkan pengguna mengganti penampilannya (misalnya mode gelap), Anda dapat menempatkan penyedia *context* di paling atas aplikasi Anda, dan menggunakan konteksnya di komponen yang membutuhkan untuk menyesuaikan tampilan visual mereka. * **Akun saat ini:** Banyak komponen yang mungkin perlu mengetahui pengguna yang sedang masuk. Menempatkannya dalam konteks akan memudahkan untuk membacanya di mana saja di dalam pohon. Beberapa aplikasi memungkinkan Anda mengoperasikan beberapa akun pada saat yang sama (misalnya untuk memberikan komentar sebagai pengguna yang berbeda). Dalam kasus tersebut, akan lebih mudah untuk membungkus bagian dari UI ke dalam penyedia bersarang dengan nilai akun saat ini yang berbeda. * **Routing:** Sebagian besar solusi *routing* menggunakan *context* secara internal untuk menyimpan rute saat ini. Dengan cara inilah setiap link "mengetahui" apakah ia aktif atau tidak. Jika Anda membuat *router* anda sendiri, Anda mungkin ingin melakukannya juga. -* **Mengelola state:** Seiring pertumbuhan aplikasi Anda, Anda mungkin akan menempatkan banyak *state* yang lebih dekat ke bagian atas aplikasi Anda. Banyak komponen yang jauh di bawahnya mungkin ingin untuk mengubahnya. Ini adalah hal yang umum untuk [menggunakan reducer bersama dengan *context*](/learn/scaling-up-with-reducer-and-context) untuk mengelola *state* yang kompleks dan mengopernya ke komponen yang jauh ke bawah tanpa terlalu banyak kerumitan. +* **Mengelola _state_:** Seiring pertumbuhan aplikasi Anda, Anda mungkin akan menempatkan banyak *state* yang lebih dekat ke bagian atas aplikasi Anda. Banyak komponen yang jauh di bawahnya mungkin ingin untuk mengubahnya. Ini adalah hal yang umum untuk [menggunakan reducer bersama dengan *context*](/learn/scaling-up-with-reducer-and-context) untuk mengelola *state* yang kompleks dan mengopernya ke komponen yang jauh ke bawah tanpa terlalu banyak kerumitan. *Context* tidak terbatas pada nilai statis. Jika anda memberikan nilai yang berbeda pada render berikutnya, React akan memperbarui semua komponen yang membacanya di bawahnya! Inilah sebabnya mengapa *context* sering digunakan bersama degan *state*. @@ -879,7 +879,7 @@ Pada umumnya, jika beberapa informasi dibutuhkan oleh komponen yang jauh di bebe #### Ganti *prop drilling* dengan *context* {/*replace-prop-drilling-with-context*/} -Pada contoh ini, mengganti checkbox akan mengubah `imageSize` *prop* yang diteruskan ke setiap ``. checkbox state akan disimpan di komponen paling atas komponen `App`, tapi tiap `` harus menyadarinya. +Pada contoh ini, mengganti checkbox akan mengubah `imageSize` *prop* yang diteruskan ke setiap ``. checkbox *state* akan disimpan di komponen paling atas komponen `App`, tapi tiap `` harus menyadarinya. Saat ini, `App` mengoper `imageSize` ke `List`, yang mana mengopernya ke tiap `Place`, yang mana mengopernya ke tiap `PlaceImage`. Hapus *prop* `imageSize`, dan sebagai gantinya oper ia dari komponen `App` ke `PlaceImage` secara langsung. From 2c0e34ca7154e76dc9350366a86efb33086f64c7 Mon Sep 17 00:00:00 2001 From: Muhammad Ridwan Date: Tue, 2 May 2023 18:33:17 +0700 Subject: [PATCH 4/5] docs: add wording `tree` --- src/content/learn/passing-data-deeply-with-context.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index bb8ac006e..c6b9dca80 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -21,7 +21,7 @@ Biasanya, Anda akan mengoper informasi dari komponen induk ke komponen anak mela [Mengoper *props*](/learn/passing-props-to-a-component) adalah cara yang bagus untuk menyalurkan data secara eksplisit melalui pohon UI Anda ke komponen yang menggunakanya. -Tapi mengoper *props* bisa menjadi bertele-tele dan tidak nyaman ketika Anda perlu mengoper beberapa *prop* secara mendalam melalui pohon, atau jika banyak komponen membutuhkan *prop* yang sama. Leluhur umum terdekat bisa jadi jauh dari komponen yang membutuhkan data, dan [memindahkan *state* ke atas](/learn/sharing-state-between-components) dapat menyebabkan yang disebut "*prop drilling*". +Tapi mengoper *props* bisa menjadi bertele-tele dan tidak nyaman ketika Anda perlu mengoper beberapa *prop* secara mendalam melalui pohon (*tree*), atau jika banyak komponen membutuhkan *prop* yang sama. Leluhur umum terdekat bisa jadi jauh dari komponen yang membutuhkan data, dan [memindahkan *state* ke atas](/learn/sharing-state-between-components) dapat menyebabkan yang disebut "*prop drilling*". From 1c44bb991a99cc4ddbad5dcafad1bc08d183b848 Mon Sep 17 00:00:00 2001 From: Muhammad Ridwan Date: Tue, 2 May 2023 18:39:42 +0700 Subject: [PATCH 5/5] docs: add wording `tree` after `pohon` --- .../learn/passing-data-deeply-with-context.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index c6b9dca80..d7adafa0d 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -4,7 +4,7 @@ title: Mengoper Data Secara Mendalam dengan Context -Biasanya, Anda akan mengoper informasi dari komponen induk ke komponen anak melalui *props*. Tapi mengoper *props* bisa menjadi bertele-tele dan merepotkan jika Anda harus mengopernya melalui banyak komponen di tengah-tengah, atau jika banyak komponen di aplikasi Anda membutuhkan informasi yang sama. *Context* memungkinkan komponen induk untuk membuat beberapa informasi tersedia di komponen lain di pohon di bawahnya—tidak peduli seberapa dalam—tanpa mengopernya secara eksplisit melalui *props*. +Biasanya, Anda akan mengoper informasi dari komponen induk ke komponen anak melalui *props*. Tapi mengoper *props* bisa menjadi bertele-tele dan merepotkan jika Anda harus mengopernya melalui banyak komponen di tengah-tengah, atau jika banyak komponen di aplikasi Anda membutuhkan informasi yang sama. *Context* memungkinkan komponen induk untuk membuat beberapa informasi tersedia di komponen lain di pohon (*tree*) di bawahnya—tidak peduli seberapa dalam—tanpa mengopernya secara eksplisit melalui *props*. @@ -19,7 +19,7 @@ Biasanya, Anda akan mengoper informasi dari komponen induk ke komponen anak mela ## Masalah ketika mengoper props {/*the-problem-with-passing-props*/} -[Mengoper *props*](/learn/passing-props-to-a-component) adalah cara yang bagus untuk menyalurkan data secara eksplisit melalui pohon UI Anda ke komponen yang menggunakanya. +[Mengoper *props*](/learn/passing-props-to-a-component) adalah cara yang bagus untuk menyalurkan data secara eksplisit melalui pohon (*tree*) UI Anda ke komponen yang menggunakanya. Tapi mengoper *props* bisa menjadi bertele-tele dan tidak nyaman ketika Anda perlu mengoper beberapa *prop* secara mendalam melalui pohon (*tree*), atau jika banyak komponen membutuhkan *prop* yang sama. Leluhur umum terdekat bisa jadi jauh dari komponen yang membutuhkan data, dan [memindahkan *state* ke atas](/learn/sharing-state-between-components) dapat menyebabkan yang disebut "*prop drilling*". @@ -38,11 +38,11 @@ Prop drilling -Bukankah lebih bagus jika ada cara untuk "memindahkan" data ke komponen di dalam pohon yang membutuhkannya tanpa harus mengoper *props*? Dengan fitur *context* React, ternyata ada! +Bukankah lebih bagus jika ada cara untuk "memindahkan" data ke komponen di dalam pohon (*tree*) yang membutuhkannya tanpa harus mengoper *props*? Dengan fitur *context* React, ternyata ada! ## *Context*: sebuah alternatif untuk mengoper *props* {/*context-an-alternative-to-passing-props*/} -*Context* memungkinkan sebuah komponen induk menyediakan data untuk seluruh pohon di bawahnya. Ada banyak kegunaan dari *context*. Berikut ini salah satu contohnya. Perhatikan komponen `Heading` ini yang menerima `level` untuk ukurannya: +*Context* memungkinkan sebuah komponen induk menyediakan data untuk seluruh pohon (*tree*) di bawahnya. Ada banyak kegunaan dari *context*. Berikut ini salah satu contohnya. Perhatikan komponen `Heading` ini yang menerima `level` untuk ukurannya: @@ -200,7 +200,7 @@ Akan lebih baik jika Anda dapat mengoper *prop* `level` ke komponen `
`
``` -Tapi bagaimana komponen `` dapat mengetahui level `
` yang terdekat? **Hal ini akan membutuhkan suatu cara untuk "meminta" data dari suatu tempat di atas pohon.** +Tapi bagaimana komponen `` dapat mengetahui level `
` yang terdekat? **Hal ini akan membutuhkan suatu cara untuk "meminta" data dari suatu tempat di atas pohon (_tree_).** Anda tidak bisa melakukannya dengan *props* sendirian. Di sinilah *context* berperan penting. Anda akan melakukannya dalam tiga langkah: @@ -208,7 +208,7 @@ Anda tidak bisa melakukannya dengan *props* sendirian. Di sinilah *context* berp 2. **Gunakan** *context* tersebut dari komponen yang membutuhkan data. (`Heading` akan menggunakan `LevelContext`.) 3. **Sediakan** *context* tersebut dari komponen yang menentukan data. (`Section` akan menyediakan `LevelContext`.) -*Context* memungkinkan sebuah induk--bahkan yang jauh sekalipun!--menyediakan beberapa data kepada seluruh komponen pohon di dalamnya. +*Context* memungkinkan sebuah induk--bahkan yang jauh sekalipun!--menyediakan beberapa data kepada seluruh komponen pohon (*tree*) di dalamnya. @@ -476,7 +476,7 @@ export default function Section({ level, children }) { } ``` -Ini memberitahu React: "jika ada komponen di dalam `
` ini yang meminta `LevelContext`, berikan `level` ini." Komponen akan menggunakan nilai dari `` terdekat di pohon UI tree di atasnya. +Ini memberitahu React: "jika ada komponen di dalam `
` ini yang meminta `LevelContext`, berikan `level` ini." Komponen akan menggunakan nilai dari `` terdekat di pohon UI (*tree*) di atasnya. @@ -699,7 +699,7 @@ Sekarang keduanya `Heading` dan `Section` membaca `LevelContext` untuk mencari t -Contoh ini menggunakan *heading levels* karena mereka menunjukkan secara visual bagaimana komponen bersarang dapat menimpa *context*. Tapi *context* juga berguna untuk banyak kasus penggunaan lainnya. Anda dapat mengoper ke bawah informasi apa pun yang dibutuhkan oleh seluruh *sub*-pohon: tema warna saat ini, pengguna yang sedang masuk, dan seterusnya. +Contoh ini menggunakan *heading levels* karena mereka menunjukkan secara visual bagaimana komponen bersarang dapat menimpa *context*. Tapi *context* juga berguna untuk banyak kasus penggunaan lainnya. Anda dapat mengoper ke bawah informasi apa pun yang dibutuhkan oleh seluruh *sub*-pohon (*tree*): tema warna saat ini, pengguna yang sedang masuk, dan seterusnya. @@ -832,7 +832,7 @@ export const LevelContext = createContext(0); -Anda tidak perlu melakukan sesuatu yang khusus untuk pekerjaan ini. `Section` menentukan *context* untuk pohon di dalamnya, jadi Anda dapat menyisipkan `` di mana saja, dan akan memiliki ukuran yang benar. Cobalah di kotak pasir di atas! +Anda tidak perlu melakukan sesuatu yang khusus untuk pekerjaan ini. `Section` menentukan *context* untuk pohon (*tree*) di dalamnya, jadi Anda dapat menyisipkan `` di mana saja, dan akan memiliki ukuran yang benar. Cobalah di kotak pasir di atas! **_Context_ memungkinkan Anda untuk menulis komponen yang "beradaptasi dengan sekitar mereka" dan menampilkan diri mereka secara berbeda tergantung di mana (atau, dalam kata lain, _dalam context apa_) mereka akan diberikan.** @@ -854,17 +854,17 @@ Jika tidak satu pun dari pendekatan ini yang cocok untuk Anda, pertimbangkan *co ## Kasus penggunakan untuk *context* {/*use-cases-for-context*/} * **Tema:** Jika aplikasi Anda memungkinkan pengguna mengganti penampilannya (misalnya mode gelap), Anda dapat menempatkan penyedia *context* di paling atas aplikasi Anda, dan menggunakan konteksnya di komponen yang membutuhkan untuk menyesuaikan tampilan visual mereka. -* **Akun saat ini:** Banyak komponen yang mungkin perlu mengetahui pengguna yang sedang masuk. Menempatkannya dalam konteks akan memudahkan untuk membacanya di mana saja di dalam pohon. Beberapa aplikasi memungkinkan Anda mengoperasikan beberapa akun pada saat yang sama (misalnya untuk memberikan komentar sebagai pengguna yang berbeda). Dalam kasus tersebut, akan lebih mudah untuk membungkus bagian dari UI ke dalam penyedia bersarang dengan nilai akun saat ini yang berbeda. +* **Akun saat ini:** Banyak komponen yang mungkin perlu mengetahui pengguna yang sedang masuk. Menempatkannya dalam konteks akan memudahkan untuk membacanya di mana saja di dalam pohon (*tree*). Beberapa aplikasi memungkinkan Anda mengoperasikan beberapa akun pada saat yang sama (misalnya untuk memberikan komentar sebagai pengguna yang berbeda). Dalam kasus tersebut, akan lebih mudah untuk membungkus bagian dari UI ke dalam penyedia bersarang dengan nilai akun saat ini yang berbeda. * **Routing:** Sebagian besar solusi *routing* menggunakan *context* secara internal untuk menyimpan rute saat ini. Dengan cara inilah setiap link "mengetahui" apakah ia aktif atau tidak. Jika Anda membuat *router* anda sendiri, Anda mungkin ingin melakukannya juga. * **Mengelola _state_:** Seiring pertumbuhan aplikasi Anda, Anda mungkin akan menempatkan banyak *state* yang lebih dekat ke bagian atas aplikasi Anda. Banyak komponen yang jauh di bawahnya mungkin ingin untuk mengubahnya. Ini adalah hal yang umum untuk [menggunakan reducer bersama dengan *context*](/learn/scaling-up-with-reducer-and-context) untuk mengelola *state* yang kompleks dan mengopernya ke komponen yang jauh ke bawah tanpa terlalu banyak kerumitan. *Context* tidak terbatas pada nilai statis. Jika anda memberikan nilai yang berbeda pada render berikutnya, React akan memperbarui semua komponen yang membacanya di bawahnya! Inilah sebabnya mengapa *context* sering digunakan bersama degan *state*. -Pada umumnya, jika beberapa informasi dibutuhkan oleh komponen yang jauh di beberapa bagian pohon, ini adalah indikasi yang bagus bahwa *context* akan membantu Anda. +Pada umumnya, jika beberapa informasi dibutuhkan oleh komponen yang jauh di beberapa bagian pohon (*tree*), ini adalah indikasi yang bagus bahwa *context* akan membantu Anda. -* *Context* memungkinkan komponen menyediakan beberapa informasi ke keseluruhan pohon di bawahnya. +* *Context* memungkinkan komponen menyediakan beberapa informasi ke keseluruhan pohon (*tree*) di bawahnya. * Untuk mengoper *context*: 1. Buat dan ekspor ia dengan `export const MyContext = createContext(defaultValue)`. 2. Oper ke `useContext(MyContext)` *Hook* untuk membacanya di komponen anak manapun, tidak peduli seberapa dalam.