Terakhir diperbarui: 2021-03-29

Penulis: Habibie Ed Dien, S.Kom., M.T.

Context dan HOC di ReactJS

Pada codelab ini Anda akan mempelajari tentang penggunaan Context dan Higher-Order Components (HOC) di ReactJS.

Pengetahun yang Anda harus miliki

Sebelum memulai codelab ini, sebaiknya Anda memiliki pengetahuan dasar tentang:

Apa yang Anda akan pelajari

Apa yang Anda perlu persiapkan

Apa itu Context ?

Di ReactJS, context merupakan fitur yang menyediakan cara untuk mengirim data melalui pohon komponen tanpa harus melalui props secara manual pada setiap level atau tingkatan.

Biasanya aplikasi React mengirim data dengan formasi top-down (parent ke child) melalui props, tetapi penggunaannya dapat menjadi rumit untuk beberapa jenis props (seperti pengaturan bahasa, tema UI) yang melibatkan banyak komponen dalam sebuah aplikasi. Context menyediakan cara untuk berbagi value antar komponen tanpa melalui props pada setiap level dari komponen.

Kapan menggunakan Context ?

Context dirancang untuk berbagi data secara "global" ke berbagai komponen React, seperti data autentikasi pengguna yang sedang aktif, tema, atau pengaturan bahasa.

Perhatikan, Sebelum Anda menggunakan Context

Context terutama digunakan ketika beberapa data dibutuhkan untuk diakses oleh banyak komponen pada setiap tingkatan (nesting levels). Gunakanlah dengan bijak karena itu akan mempersulit penggunaan kembali (reuse) komponen yang ada.

Context API

React.createContext

const MyContext = React.createContext(defaultValue);

Membuat sebuah objek Context yang berguna ketika melakukan render komponen yang terikat dengan komponen lain. Objek context akan membaca context value yang terdekat di dalam tag Provider yang ada diatasnya.

Argumen defaultValue hanya digunakan ketika sebuah komponen tidak menemukan yang cocok terhadap tag Provider yang berada diatasnya.

Context.Provider

<MyContext.Provider value={/* some value */}>

Setiap objek Context terbentuk karena ada komponen Provider React yang mengizinkan untuk menggunakan komponen lain yang terikat terhadap perubahan context.

Komponen Provider menerima value dari prop untuk diteruskan ke komponen lain yang merupakan turunan dari Provider ini. Satu Provider dapat terkoneksi dengan banyak consumers. Provider dapat diletakkan secara bersarang untuk nilai yang di-override terhadap komponen lain yang ada didalamnya.

Class.contextType

class MyClass extends React.Component {
  componentDidMount() {
    let value = this.context;
    /* perform a side-effect at mount using the value of MyContext */
  }
  componentDidUpdate() {
    let value = this.context;
    /* ... */
  }
  componentWillUnmount() {
    let value = this.context;
    /* ... */
  }
  render() {
    let value = this.context;
    /* render something based on the value of MyContext */
  }
}

MyClass.contextType = MyContext;

Properti contextType pada sebuah class dapat dibuat sebuah objek Context dengan React.createContext(). Properti ini bermanfaat untuk menggunakan value terdekat saat ini pada jenis Context dengan this.context. Bisa diletakkan pada method lifecycle apapun termasuk di dalam fungsi render.

Context.Consumer

<MyContext.Consumer>
  {value => /* render something based on the context value */}
</MyContext.Consumer>

Komponen react yang terikat akan berubah sesuai nilai context. Consumer ini berguna untuk mengikat context komponen yang ada didalamnya.

Context.displayName

Objek context memiliki properti displayName berupa string. React DevTools menggunakan nilai string ini untuk menentukan nilai context mana yang perlu untuk ditampilkan.

Contohnya, komponen berikut akan menampilkan MyDisplayName di DevTools:

const MyContext = React.createContext(/* some value */);
MyContext.displayName = 'MyDisplayName';

<MyContext.Provider> // "MyDisplayName.Provider" in DevTools
<MyContext.Consumer> // "MyDisplayName.Consumer" in DevTools

Untuk mempelajari lebih lanjut tentang Context dapat membaca di sini.

HOC adalah teknik lanjutan untuk membuat komponen baru dari komponen yang sudah ada. Jadi, kita bisa membuat komponen baru yang memiliki fitur atau fungsi tambahan dengan cara komposisi yaitu satu atau lebih komponen yang digabung dan dibungkus dengan komponen lain menjadi sebuah komponen baru.

Contohnya ada komponen A dan B. HOC dapat membuat komponen C yang berisi komponen A dan B ditambah fitur dan komponen lain. Sebagai ilustrasi, perhatikan gambar berikut ini.

Untuk mempelajari lebih lanjut tentang HOC dapat membaca di sini.

Pada praktikum ini, kita akan membuat aplikasi sederhana yang dapat mengubah warna sesuai warna button yang diklik seperti pada gambar berikut ini.

Untuk membuat aplikasi tersebut, silakan lakukan langkah-langkah praktikum berikut ini.

  1. Buka project React di VS Code yang sebelumnya telah dibuat atau bisa membuat project React baru dengan perintah di console: npx create-react-app theme-app
  2. Buatlah folder baru bernama ThemeContext di dalam folder src, sehingga menjadi src/ThemeContext.
  3. Buatlah file theme-context.js di src/ThemeContext, kemudian isi kodenya adalah sebagai berikut.
import React from "react";

export const ThemeContext = React.createContext(
// default values digunakan oleh Consumer ketika tidak ada  
// yang cocok dengan Provider yang berada diatasnya
  {
    themeContext: {
       color: 'blue',
       setColor: () => {}
    }
  }
)
  1. Lalu buatlah file withTheme.js di src/ThemeContext dan isi kode programnya adalah sebagai berikut:
import { ThemeContext } from './theme-context';

export function withTheme (Component) {
  return function ThemeComponent (props) {
    return (
      <ThemeContext.Consumer>
        {
          (contexts) => <Component {...props} {...contexts} />
        }
      </ThemeContext.Consumer>
    )
  }
}
  1. Kemudian buatlah file ThemeProvider.js di src/ThemeContext dengan isi kode sebagai berikut:
import React from 'react';
import { ThemeContext } from './theme-context';

export default class ThemeProvider extends React.Component {
  constructor() {
    super();
    this.state = {
      setColor: this.setColor.bind(this),
      color: "yellow"
    };
  }

  setColor (color) {
    this.setState({ color });
  }

  render () {
    return (
      <ThemeContext.Provider value={{
        themeContext: {
          ...this.state
        }
      }}>
        {this.props.children}
      </ThemeContext.Provider>
    )
  }
}
  1. Selanjutnya buatlah file di src/Menu.js dengan kode berikut ini.
import { withTheme } from "./ThemeContext/withTheme";

const Menu = props => (
  <div style={{ backgroundColor: props.themeContext.color }}>
    Menu
  </div>
);

export default withTheme(Menu);
  1. Lalu buatlah file di src/SetColor.js dengan kode berikut ini.
import { withTheme } from "./ThemeContext/withTheme";

const SetColor = props => (
  <div>
    <button onClick={() => props.themeContext.setColor("red")}>Red</button>
    <button onClick={() => props.themeContext.setColor("blue")}>Blue</button>
  </div>
);

export default withTheme(SetColor);
  1. Akhirnya file src/App.js kita edit dengan kode berikut ini.
import ThemeProvider from "./ThemeContext/ThemeProvider";
import Menu from "./Menu";
import SetColor from "./SetColor";

export default function App () {
  return (
    <ThemeProvider>
      <Menu />
      <br />
      <SetColor />
    </ThemeProvider>
  )
}

Untuk melihat hasilnya di browser, silakan run npm start di console atau terminal. Seharusnya tombol sudah berfungsi untuk mengubah warna tema. Jangan lupa untuk file src/index.js sudah melakukan render App.

Struktur file dan folder Anda di folder src seharusnya seperti berikut:

index.js
App.js
SetColor.js
Menu.js
ThemeContext/
   theme-context.js
   withTheme.js
   ThemeProvider.js

Selamat, Anda telah berhasil menyelesaikan codelab ini. Semoga mendapatkan ilmu yang bermanfaat.

Apa selanjutnya?

Silakan cek beberapa sumber belajar lainnya...

Referensi