Terakhir diperbarui: 2021-04-19

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

Global API dan Hooks di ReactJS

Pada codelab ini Anda akan mempelajari tentang penggunaan Global API dan Hooks 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 Global API ?

Pada Codelab 5 kita pernah mempelajari tentang interaksi dengan API. Kita dihadapkan dengan mengelola banyak daftar alamat API yang disediakan dan mengumpulkannya menjadi satu kelompok. Sehingga kita dapat menambah, mengurangi, ataupun memperbaiki daftar API pada satu tempat.

Salah satu caranya adalah dengan mengelola/mengatur pemanggilan API secara GLOBAL, sehingga kita tidak perlu melakukan "coding ulang" API yang memiliki karakter yang sama. Contoh saat kita memanggil API (GET) untuk mendapatkan list Artikel, list komentar, dan list pengguna. API untuk ketiga proses tersebut sebenarnya sama, yang membedakan hanya alamat url API yang dituju, sehingga kita bisa meletakkan list API pada satu tempat untuk mempermudah dalam pengelolaannya.

Pada codelab ini, kita menggunakan materi dari Codelab 5 – API di ReactJS. Sehingga kita dapat memahami perbedaan antara Codelab 5 yang hanya melakukan interaksi satu API dengan codelab ini yang mengelola daftar list API ke dalam satu tempat, sehingga proses manajemen API lebih mudah dan cepat.

Kelebihan menggunakan Global API

Terpusat. API yang dibuat atau yang akan dipanggil terpusat pada satu tempat.

Kustomisasi. Mudah dan efisien saat melakukan kustomisasi maupun perbaikan alamat API.

Mudah dikelola. Berhubung list API berada pada satu tempat, sehingga proses mengelola daftar API baik penambahan, pengurangan, maupun memperbaiki API (perubahan alamat API) bisa dilakukan dengan mudah.

Terhindar dari proses yang sama (redundansi). Berhubung daftar API dalam satu tempat sehingga kita bisa memantau dan meminimalisir proses yang sama atau pembuatan API yang sama persis.

Pada praktikum ini, dibagi menjadi beberapa bagian praktikum yaitu membuat global API untuk service GET, POST, Delete, dan manajemennya. Kita mulai dengan membuat global API untuk service GET sebagai berikut.

Membuat Global API Service GET

  1. Anda dapat membuat project baru React atau melanjutkan praktikum dari Codelab 5 tentang interaksi dengan API.
  2. Buatlah folder services dalam folder src, lalu buat file index.js di dalam folder services seperti pada gambar berikut.

  1. Buat konstanta baseUrlApi di src/services/index.js sebagai alamat url utama API yang digunakan. Anda dapat mengaturnya secara terpusat di variabel baseUrlApi ini.
const baseUrlApi = 'http://localhost:3001';
  1. Kemudian buat konstanta GetAPI untuk service GET.
const GetAPI = (path) => {
  const promise = new Promise((resolve, reject) => {
    fetch(`${baseUrlApi}/${path}`)
      .then(response => response.json())
      .then((result) => {
        resolve(result);
      }, (err) => {
        reject(err);
      })
  })
  return promise;
}
  1. Lalu buat konstanta getNewsBlog untuk mendapatkan isi artikel. Dalam konstanta ini terdapat fungsi yang memanggil GetAPI berisi parameter posts yang diurutkan secara descending berdasarkan atribut id.
const getNewsBlog = () => GetAPI('posts?_sort=id&_order=desc');
  1. Selanjutnya buat konstanta API yang nanti akan diisi service GET, POST, dan DELETE.
const API = {
  getNewsBlog
}

export default API;
  1. Buat folder src/components dan isi file baru dengan nama BlogPost.js.
import React from 'react';
import API from '../services';
  1. Buat komponen DaftarArtikel di src/components/BlogPost.js untuk menampilkan isi artikel.
function DaftarArtikel(props){
  return(
    <div>
      <h3>{props.judul}</h3>
      <div>{props.isiArtikel}</div>
    </div>
  );
}
  1. Kemudian buat class BlogPost
export default class BlogPost extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      dataArtikel: []      // untuk menampung data API
    };
  }

  ambilDataDariServerAPI = () => {
    API.getNewsBlog().then(result => {
      this.setState({
        dataArtikel: result
      })
    })
  }

  componentDidMount () {
    this.ambilDataDariServerAPI()
  }

  render(){
    const { dataArtikel } = this.state;

    return (
      <div>
        <h2>Daftar Artikel</h2>
        {
          dataArtikel.map(artikel => {
            return <DaftarArtikel key={artikel.id} judul={artikel.title} isiArtikel={artikel.body} />
          })
        }
      </div>
    );
  }
}
  1. Kemudian pindah ke file src/App.js kita panggil class BlogPost untuk dirender.
import React from 'react';
import BlogPost from './components/BlogPost';

class App extends React.Component {

  render () {
    return (
      <div>
        <BlogPost />
      </div>
    );
  }
}

export default App;
  1. Selanjutnya pindah ke src/index.js seperti biasa kita render.
import ReactDOM from 'react-dom';
import App from './App.js';

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
  1. Kemudian save semua dan run npm start untuk melihat hasilnya di browser. Apa yang terjadi ? Apakah tampil data artikel tersebut ?

Membuat Restful API Lokal

  1. Dari praktikum sebelumnya, tentu data artikel belum tampil karena server API belum kita jalankan di alamat http://localhost:3001 . Kita siapkan server API dengan membuat file listArtikel.json di root project React kita.

  1. Buka file listArtikel.json lalu isi datanya dengan copy dari https://jsonplaceholder.typicode.com/posts

  1. Setelah itu save, lalu buka tab terminal baru di vs-code (agar server npm start milik react tadi tetap running) dengan cara klik icon + seperti di gambar berikut.

  1. Ketikkan perintah berikut dan pastikan Anda berada di root project listArtikel.json berada.
json-server --watch listArtikel.json --port 3001
  1. Sekarang Anda dapat merefresh halaman react di browser dan seharusnya data artikel sudah tampil sesuai isi dari listArtikel.json.

Membuat Global API Service POST

  1. Buka file src/services/index.js dan tambahkan kode POST berikut ini.
const PostAPI = (path, data) => {
  const promise = new Promise((resolve, reject) => {
    fetch(`${baseUrlApi}/${path}`, {
      method: 'post',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(data)
    })
      .then((result) => {
        resolve(result);
      }, (err) => {
        reject(err);
      })
  })
  return promise;
}
  1. Kemudian tambahkan konstanta postNewsBlog untuk data yang dikirim.
const postNewsBlog = (dataYgDikirim) => PostAPI('posts', dataYgDikirim);
  1. Lalu bagian konstanta API kita tambahkan method di atas seperti pada gambar berikut.

  1. Selanjutnya pindah ke file src/components/BlogPost.js tambahkan variabel postArtikel untuk menampung data artikel yang akan dikirim melalui method POST.

  1. Kemudian bagian render() kita tambahkan form untuk submit artikel seperti kode berikut.
render () {
    const { dataArtikel, postArtikel } = this.state;

    return (
      <div>
        <div>
          <form onSubmit={this.handleTombolSimpan}>
            <label>
              Judul Artikel:
              <input type="text" name="title" defaultValue={postArtikel.title} onChange={this.handleOnChange} />
            </label>
            <label>
              Isi Artikel:
              <input type="text" name="body" defaultValue={postArtikel.body} onChange={this.handleOnChange} />
            </label>
            <input type="submit" value="Simpan" />
          </form>
        </div>
        <hr></hr>
        <h2>Daftar Artikel</h2>
        {
          dataArtikel.map(artikel => {
            return <DaftarArtikel key={artikel.id} judul={artikel.title} isiArtikel={artikel.body} />
          })
        }
      </div>
    );
  }
  1. Selanjutnya kita buat fungsi handleTombolSimpan di dalam class BlogPost.
handleTombolSimpan = (e) => {
    e.preventDefault();

    API.postNewsBlog(this.state.postArtikel)
      .then((response) => {
        this.ambilDataDariServerAPI();    // refresh data
        alert('Data berhasil disimpan!');
      });
  }
  1. Lalu buat fungsi handleOnChange
handleOnChange = (e) => {
    let name = e.target.name;
    let value = e.target.value;
    this.setState(prevState => {
      prevState.postArtikel[name] = value;
      return {
        postArtikel: prevState.postArtikel
      };
    });
  }
  1. Save semua pekerjaan dan silakan refresh di browser. Apakah sudah bisa menambahkan data artikel baru ?

Membuat Global API Service DELETE

  1. Buka file src/services/index.js dan tambahkan kode DELETE berikut ini.
const DeleteAPI = (path, data) => {
  const promise = new Promise((resolve, reject) => {
    fetch(`${baseUrlApi}/${path}/${data}`, { method: 'DELETE' })
      .then((result) => {
        resolve(result);
      }, (err) => {
        reject(err);
      })
  })
  return promise;
}
  1. Kemudian tambahkan konstanta deleteNewsBlog untuk data yang dikirim.
const deleteNewsBlog = (dataYgDihapus) => DeleteAPI('posts', dataYgDihapus);
  1. Lalu bagian konstanta API kita tambahkan method di atas seperti pada gambar berikut.

  1. Selanjutnya pindah ke file src/components/BlogPost.js bagian fungsi render() tambahkan tombol Hapus.
<h2>Daftar Artikel</h2>
        {
          dataArtikel.map(artikel => {
            return (
              <div key={artikel.id}>
                <DaftarArtikel judul={artikel.title} isiArtikel={artikel.body} />
                <Button variant="danger" value={artikel.id} onClick={this.handleTombolHapus}>Hapus</Button>
                <hr></hr>
              </div>
            )
          })
        }
  1. Terakhir buat fungsi handleTombolHapus yang berisi kode berikut.
handleTombolHapus = (e) => {
    e.preventDefault();

    API.deleteNewsBlog(e.target.value)
      .then((response) => {
        this.ambilDataDariServerAPI();    // refresh data
        alert('Data berhasil dihapus!');
      });
  }
  1. Silakan coba refresh aplikasi react Anda di browser, seharusnya sudah muncul tombol untuk menghapus artikel yang dipilih.

Mengelola Global API Service

Pada global API yang telah kita lakukan pada praktikum di atas. Kita mengetahui bahwa saat kita benar-benar melakukan coding untuk membuat API, kita akan dihadapkan pada banyak URL API yang akan kita sediakan. Sehingga kita butuh mengelola Global API untuk lebih teratur.

Salah satu cara untuk mengelola Global API adalah dengan memisahkan API berdasarkan action-nya (GET, POST, DELETE). Sehingga jika terjadi error pada DELETE API, kita cukup akan membuka Global API bagian DELETE yang akan kita perbaiki.

Silakan lakukan langkah-langkah praktikum berikut ini.

  1. Buat folder baru di src/services/API dan src/services/Artikel beserta file baru didalamnya seperti pada struktur di bawah ini.

  1. Isi file src/services/API/Config.js adalah sebagai berikut. File Config.js ini bisa menampung variabel global yang digunakan selama proses API.

  1. Isi file src/services/API/Get.js adalah sebagai berikut.

  1. Selanjutnya file Post.js dan Delete.js isinya sesuai dengan praktikum sebelumnya, hanya saja dipindah di file terpisah. Silakan disesuaikan seperti pada file Get.js!
  2. Kemudian pada file src/services/Artikel/index.js berubah menjadi seperti berikut ini.

  1. Terakhir menyesuaikan import pada bagian komponen BlogPost.js dengan memanggil API pada bagian folder Artikel.

  1. Simpan semua pekerjaan dan lihat hasilnya di browser. Seharusnya aplikasi react tetap berjalan normal seperti sebelumnya. Hanya saja struktur folder API yang telah kita buat menjadi lebih teratur dan mudah untuk dikelola.

Buatlah folder baru di src/services/Komentar yang digunakan untuk mengelola data komentar. Buatlah komponen baru dengan nama Komentar.js di folder components yang berfungsi untuk mengelola data komentar berdasarkan API yang telah dibuat!

Jangan lupa menambahkan objek di database json "comment" untuk menampung data komentar. Atribut bisa terdiri dari userId, nama, komentar, dan id.

Hook dalam bahasa inggris jika diterjemahkan ke bahasa indonesia mempunyai arti "menghubungkan" atau "mengaitkan". Dalam bentuk plural hooks berarti banyak yang dihubungkan.

Hooks merupakan fungsi yang memungkinkan Anda untuk "mengaitkan" state dan fitur-fitur lifecycle React dari function component. Hooks tidak dapat berfungsi didalam kelas — Hooks memungkinkan menggunakan React tanpa kelas. (tidak direkomendasikan membuat ulang komponen yang sudah ada tetapi Anda dapat menggunakan Hooks untuk komponen yang baru jika diinginkan.)

Hooks merupakan fitur baru di React sejak versi 16.8. Dengan Hooks, kita dapat menggunakan state dan fitur React yang lain tanpa perlu menulis sebuah kelas baru. Perhatikan contoh kode di bawah ini.

import React, { useState } from 'react';

function ContohHook () {
  // Mendeklarasikan variabel state baru, yaitu "count"
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Anda mengklik {count} kali</p>
      <button onClick={() => setCount(count + 1)}>
        Klik aku
      </button>
    </div>
  );
}

export default ContohHook;

useState adalah fungsi baru yang akan kita pelajari di sini. Kode diatas dapat merender tampilan counter dengan button yang bisa melalukan increment. Anda dapat mencobanya langsung pada aplikasi react Anda.

Hooks Tidak Merusak Struktur Komponen yang Sudah Ada

Sebelum kita melanjutkan, perlu diingat bahwa hooks itu:

Selain itu ada beberapa hal yang perlu diperhatikan terkait hooks, yaitu:

Fitur Class tidak akan dihapus dari React. Hadirnya fitur hooks bukan berarti menggantikan fitur class yang telah Anda pelajari sebelumnya. Untuk strategi penggunaan hooks secara bertahap, dapat dibaca pada link ini.

Hooks tidak akan menggantikan pengetahuan tentang konsep React yang telah Anda pelajari. Justru fitur Hooks menyediakan akses langsung API ke konsep React yang sudah dipelajari seperti props, state, context, refs, dan lifecycle.

Untuk mempelajari lebih lanjut tentang Hooks dapat membaca di sini.

Mengapa ada Hooks ?

Beberapa permasalahan yang dihadapi sebelum hadirnya fitur hooks adalah sebagai berikut.

Sulitnya menggunakan kembali stateful logic antar komponen

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

Apa selanjutnya?

Silakan cek beberapa sumber belajar lainnya...

Referensi