Advertisement
  1. Code
  2. React

Pengenalan yang Lembut terhadap Komponen-Komponen yang Lebih Tinggi dalam React

Scroll to top
Read Time: 10 min
This post is part of a series called A Gentle Introduction to Higher Order Components in React.
A Gentle Introduction to HOC in React: Learn by Example
A Gentle Introduction to Higher-Order Components in React

Indonesian (Bahasa Indonesia) translation by Febri Ardian Sanjoyo (you can also view the original English article)

High-Order Components (HOCs) adalah teknik yang menarik dalam React digunakan untuk refactor komponen serupa yang berbagi logika hampir sama. Saya tahu bahwa itu terdengar abstrak dan maju. Namun, ini adalah pola arsitektur yang tidak spesifik untuk React, dan karenanya Anda dapat menggunakan pendekatan untuk melakukan banyak hal.

Misalnya, Anda dapat menggunakannya untuk menambahkan indikator pemuatan ke komponen tertentu tanpa mengutak-atik komponen asli, atau Anda bisa menyembunyikan alat bantu komponen untuk membuatnya kurang verbose. Aplikasinya banyak, dan saya sudah mencoba meliput sebagian besar dari itu dalam tutorial ini.

Ada beberapa tutorial lain yang mengajarkan Anda tentang HOC, tetapi kebanyakan dari mereka dimaksudkan untuk pengembang React lanjutan. Ketika saya mulai belajar React, saya kesulitan memahami konsep komponen tingkat tinggi dan bagaimana saya bisa memasukkan HOC dalam proyek saya untuk menulis kode yang lebih baik. Artikel ini akan menjelaskan semua yang perlu Anda ketahui tentang HOC dari awal hingga akhir.

Ikhtisar

Tutorial ini dibagi menjadi tiga bagian. Bagian pertama akan berfungsi sebagai pengantar konsep komponen tingkat tinggi. Di sini, kita akan berbicara tentang sintaks yang perlu Anda ketahui sebelum melihat fungsi tingkat tinggi dan HOC. Bagian kedua adalah bagian paling menarik dari seri ini di mana Anda akan melihat contoh-contoh praktis dari HOC. Kami akan menggunakan HOC untuk membuat form, otorisasi, dan banyak hal lainnya.

Di bagian ketiga dari tutorial ini, kita akan lebih fokus pada praktik terbaik dan hal-hal yang perlu dipertimbangkan saat menerapkan hight-order components. Kami juga akan melihat sekilas pola alternatif untuk sharing kode di React, seperti alat peraga Render.

Sebelum memulai, mungkin ada baiknya untuk melihat tutorial tentang komponen Stateful vs. Stateless untuk memahami arsitektur komponen React lebih baik.

ES6 Syntax Cheatsheet

Kita akan segera mengotori tangan kita. Tetapi sebelum kita melakukannya, inilah beberapa hal yang menurut saya perlu Anda ketahui. Saya lebih suka menggunakan sintaks ES6 sedapat mungkin, dan itu bekerja hebat dengan HOC. Sebagai seorang pemula, HOC masuk akal, tetapi beberapa sintaks ES6 tidak. Jadi saya merekomendasikan untuk melalui bagian ini sekali, dan Anda dapat kembali ke sini nanti untuk referensi.

Fungsi Panah

Fungsi panah adalah ekspresi fungsi biasa, tetapi dengan sintaks yang lebih pendek. Mereka paling cocok untuk fungsi non-method, dan itulah yang kami sangat tertarik. Berikut ini beberapa contoh untuk Anda mulai:

Fungsi Tanpa Parameter

1
/* Functions without parameters */
2
function () {
3
    return "This is a function expression";
4
}
5
6
// is equivalent to

7
8
() => {
9
 return "This is an arrow function expression"
10
}
11
12
// or 

13
14
() => "Arrow with a shorter syntax"

Fungsi Dengan Satu Parameter

1
/* Function with a single parameter */
2
3
function (param) {
4
  return { title: "This function accepts a parameter and returns an object",
5
          params: param}
6
}
7
8
// is syntax-equivalent to 

9
10
param => {
11
    return { title: "This arrow function accepts a single parameter",
12
        params: param }
13
}
14

Fungsi Dengan Beberapa Parameter

1
/* Function with multiple parameters */
2
3
function (param1, param2) {
4
  return { title: "This function accepts multiple parameters",
5
          params: [param1,param2]}
6
}
7
8
// is syntax-equivalent to 

9
10
(param1, param2) => {
11
    return {title: "Arrow function with multiple parameters",
12
    params: [param1, param2]
13
    }
14
}
15
16
// or

17
18
(param1, param2) => ({
19
      title: "Arrow function with multiple parameters",
20
    params: [param1, param2]
21
    })

Currying dalam Pemrograman Fungsional

Meskipun namanya menunjukkan bahwa itu ada hubungannya dengan hidangan eksotis dari masakan India yang populer, itu tidak. Currying membantu Anda memecah fungsi yang mengambil banyak argumen ke dalam serangkaian fungsi yang mengambil satu argumen pada suatu waktu. Berikut ini contohnya:

1
//Usual sum function

2
const sum = (a, b) => a + b
3
4
//Curried sum function 

5
const curriedSum = function (a) {
6
    return function (b) {
7
        return a+b
8
    }
9
10
//Curried sum function using arrow syntax

11
const curriedSum = a => b => a+b
12
13
curriedSum(5)(4)
14
//9

Fungsi hanya menerima satu argumen dan mengembalikan fungsi yang mengambil argumen lain, dan ini berlanjut sampai semua argumen dipenuhi.

1
curriedSum
2
// (a) => (b) => a+b

3
4
curriedSum(4)
5
6
// (b) => 4+b

7
8
curriedSum(4)(5)
9
10
//4+5

Istilah yang terkait erat disebut aplikasi parsial. Aplikasi parsial berhubungan dengan membuat fungsi baru dengan mengisi sebagian argumen dari fungsi yang ada. Fungsi yang baru dibuat akan memiliki arity (yang diterjemahkan ke jumlah argumen) kurang dari fungsi aslinya.

Spread Syntax

Spread operators menyebarkan isi dari array, string, atau ekspresi objek. Berikut adalah daftar hal-hal yang dapat Anda lakukan dengan spread operator

Spread Sintax dalam Function Calls

1
/*Spread Syntax in Function Calls */
2
const add = (x,y,z) => x+y+z
3
4
const args = [1,2,3]
5
6
add(...args) 
7
// 6

8

Spread Sintax dalam Array Literals

1
/* Spread in Array Literals */
2
3
const twoAndThree = ['two', 'three']; 
4
const numbers = ['one', ...twoAndThree, 'four', 'five']; 
5
// ["one", "two", "three", "four", "five"]
6

Spread Syntax in Object Literals

1
/* Spread in Object Literals */
2
3
const contactName = {
4
  name: {
5
    first: "Foo",
6
    middle: "Lux",
7
    last: "Bar"
8
  }
9
}
10
const contactData = {
11
  email: "fooluxbar@example.com",
12
  phone: "1234567890"
13
}
14
15
const contact = {...contactName, ...contactData}
16
/* { 

17
    name: {

18
        first: "Foo",

19
        middle: "Lux",

20
        last: "Bar"

21
    }

22
    email: "fooluxbar@example.com"

23
    phone: "1234567890"

24
  }

25
  

26
*/
27
        

Saya pribadi menyukai cara di mana tiga titik dapat memudahkan Anda untuk melewati alat peraga yang ada ke komponen anak atau membuat alat peraga baru.

Operator Spread dalam React

1
const ParentComponent = (props) => {
2
  const newProps = { foo: 'default' };
3
  
4
  return (
5
      <ChildComponent 
6
    	{...props} {...newProps} 
7
  	/>

8
  )
9
}

Sekarang kita tahu sintaks ES6 dasar untuk membangun HOC, mari kita lihat apa itu.

Higher-Order Functions

Apakah higher-order function itu? Wikipedia memiliki definisi yang jelas:

Dalam matematika dan ilmu komputer, higher-order function (juga fungsional, bentuk fungsional atau functor) adalah fungsi yang baik mengambil satu atau lebih fungsi sebagai argumen atau mengembalikan fungsi sebagai hasilnya atau keduanya.

Anda mungkin pernah menggunakan fungsi tingkat tinggi dalam JavaScript sebelum dalam satu bentuk atau lainnya karena itulah cara JavaScript bekerja. Melewati fungsi anonim atau panggilan balik sebagai argumen atau fungsi yang mengembalikan fungsi lain — semua ini berada di bawah fungsi hight-order. Kode di bawah ini menciptakan fungsi kalkulator yang merupakan tatanan yang lebih tinggi di alam.

1
const calculator = (inputFunction) => 
2
    	(...args) => {
3
        
4
       const resultValue = inputFunction(...args);
5
       console.log(resultValue);
6
          
7
       return resultValue;
8
        }
9
10
const add = (...all) => {
11
	return all.reduce( (a,b) => a+b,0)	;
12
  
13
	}
14
  
15
 
16
const multiply = (...all) => {
17
  return all.reduce((a,b)=> a*b,1);
18
 
19
  }

Mari kita lihat lebih dalam ini. Calculator() menerima fungsi sebagai input dan mengembalikan fungsi lain — ini sangat cocok dengan definisi kita tentang fungsi hight order. Karena kami telah menggunakan sintaks parameter sisanya, fungsi yang dikembalikan mengumpulkan semua argumennya di dalam array.

Kemudian, fungsi input dipanggil dengan semua argumen yang dilewatkan, dan hasilnya dicatat ke konsol. Jadi kalkulator adalah fungsi yang lebih kari, lebih tinggi, dan Anda dapat menggunakan kalkulator seperti ini:

1
calculator(multiply)(2,4);
2
// returns 8

3
4
calculator(add)(3,6,9,12,15,18); 
5
// returns 63

Hubungkan fungsi seperti add() atau multiply() dan sejumlah parameter, dan calculator() akan mengambilnya dari sana. Jadi calculator adalah wadah yang memperluas fungsi add() dan multiply(). Ini memberi kita kemampuan untuk menangani masalah pada tingkat yang lebih tinggi atau lebih abstrak. Sepintas, manfaat dari pendekatan ini termasuk:

  1. Kode dapat digunakan kembali di beberapa fungsi.
  2. Anda dapat menambahkan fungsionalitas tambahan umum untuk semua operasi aritmatika di container level.
  3. Ini lebih mudah dibaca, dan tujuan programmer lebih baik diungkapkan.

Sekarang kita memiliki gagasan yang bagus tentang fungsi tingkat tinggi, mari kita lihat apa yang bisa dilakukan oleh higher-order components.

Higher-Order Components

higher-order component adalah fungsi yang menerima komponen sebagai argumen dan mengembalikan versi tambahan dari komponen itu.

1
(InputComponent) => {
2
    return ExtendedComponent 
3
    }
4
    
5
// or alternatively

6
7
InputComponent => ExtendedComponent
8

The ExtendedComponent menyusun InputComponent. The ExtendedComponent seperti wadah. Ini menjadikan InputComponent, tetapi karena kita mengembalikan komponen baru, itu menambahkan lapisan tambahan abstraksi. Anda dapat menggunakan lapisan ini untuk menambahkan status, perilaku, atau bahkan style. Anda bahkan dapat memutuskan untuk tidak membuat InputComponent sama sekali jika Anda menginginkan — HOC mampu melakukan itu dan banyak lagi.

Gambar di bawah ini harus membersihkan suasana kebingungan jika ada.

Higher Order Components Overview Higher Order Components Overview Higher Order Components Overview

Cukup dengan teori — mari kita dapatkan kodenya. Berikut ini contoh HOC yang sangat sederhana yang membungkus komponen input di sekitar tag <div>. Mulai sekarang, saya akan mengacu pada InputComponent sebagai WrappedComponent karena itulah konvensi. Namun, Anda dapat menyebutnya apa pun yang Anda inginkan.

1
/* The `with` prefix for the function name is a naming convention.

2
You can name your function anything you want as long as it's meaningful 

3
*/
4
5
const withGreyBg = WrappedComponent => class NewComponent extends Component {
6
  
7
  const bgStyle = {
8
  		backgroundColor: 'grey',
9
	};
10
    
11
  render() {
12
    return (
13
      <div className="wrapper" style={bgStyle}>
14
15
        <WrappedComponent {...this.props} />

16
      </div>

17
    );
18
  }
19
};
20
21
const SmallCardWithGreyBg = withGreyBg(SmallCard);
22
const BigCardWithGreyBg = withGreyBg(BigCard);
23
const HugeCardWithGreyBg = withGreyBg(HugeCard);
24
25
class CardsDemo extends Component {
26
    render() {
27
        <SmallCardWithGreyBg {...this.props} />

28
        <BigCardWithGreyBg {...this.props} />

29
        <HugeCardWithGreyBg {...this.props />
30
    }
31
}

Fungsi withGreyBg mengambil komponen sebagai input dan mengembalikan komponen baru. Alih-alih langsung menyusun komponen-komponen Card dan melampirkan tag style ke masing-masing komponen, kita membuat HOC yang melayani tujuan ini. Higher-order component membungkus komponen asli dan menambahkan tag <div> di sekelilingnya. Perlu dicatat bahwa Anda harus secara manual mewariskan properti di sini pada dua tingkat. Kita belum melakukan sesuatu yang wah, tapi inilah penampilan HOC yang normal. Gambar di bawah ini menunjukkan contoh withGreyBg() secara lebih terperinci.

Higher-Order Components example in ReactHigher-Order Components example in ReactHigher-Order Components example in React

Meskipun ini mungkin tidak tampak sangat berguna saat ini, manfaatnya tidak sepele. Pertimbangkan skenario ini. Anda menggunakan React router, dan Anda perlu menjaga beberapa rute agar terlindungi — jika pengguna tidak diautentikasi, semua permintaan ke rute ini harus dialihkan ke /login. Alih-alih menduplikasi kode otentikasi, kita dapat menggunakan HOC untuk secara efektif mengelola rute yang dilindungi. Ingin tahu bagaimana caranya? Kami akan membahasnya dan banyak lagi di tutorial selanjutnya.

Catatan: Ada fitur yang diusulkan dalam ECMAScript yang disebut dekorator yang memudahkan penggunaan HOC. Namun, ini masih merupakan fitur eksperimental, jadi saya memutuskan untuk tidak menggunakannya dalam tutorial ini. Jika Anda menggunakan creat-react-app, Anda harus keluar terlebih dahulu untuk menggunakan dekorator. Jika Anda menjalankan versi terbaru Babel (Babel 7), Anda hanya perlu menginstal babel-preset-stage-0 dan kemudian menambahkannya ke daftar plugin di webpack.config.dev.js Anda sebagai berikut.

1
// Process JS with Babel.

2
        {
3
            test: /\.(js|jsx|mjs)$/,
4
            include: paths.appSrc,
5
            loader: require.resolve('babel-loader'),
6
            options: {
7
              
8
              // This is a feature of `babel-loader` for webpack (not Babel itself).

9
              // It enables caching results in ./node_modules/.cache/babel-loader/

10
              // directory for faster rebuilds.

11
              cacheDirectory: true,
12
              presets: ['stage-0']
13
        },

Ringkasan

Dalam tutorial ini, kami belajar konsep dasar HOC. HOC adalah teknik populer untuk membangun komponen yang dapat digunakan kembali. Kita mulai dengan diskusi tentang sintaks ES6 dasar sehingga akan lebih mudah bagi Anda untuk terbiasa dengan fungsi panah dan menulis kode JavaScript modern.

Kita kemudian melihat higher-order function dan cara kerjanya. Akhirnya, kita menyentuh higher-order components dan menciptakan HOC dari awal.

Selanjutnya, kita akan membahas teknik HOC yang berbeda dengan contoh-contoh praktis. Tetap disini hingga saat itu. Bagi pengalaman anda di bagian komentar.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.