Implementasi untuk aplikasi yang membutuhkan data dari API

Sekarang, mari kita lanjutkan dengan materi **Implementasi React Query untuk Aplikasi yang Mengambil Data dari API**. Dalam contoh ini, kita akan menggunakan aplikasi React untuk mengkonsumsi data dari API eksternal dengan fitur pengambilan dan mutasi data yang telah kita pelajari sebelumnya.

### Studi Kasus: Aplikasi Todo List dengan API

Aplikasi ini akan memiliki dua fitur utama:
1. **Pengambilan Data (GET)** – Mengambil daftar todo dari API menggunakan `useQuery`.
2. **Menambah Data (POST)** – Menambahkan todo baru ke dalam daftar menggunakan `useMutation`.

Kita akan menggunakan API publik dari **JSONPlaceholder** untuk mensimulasikan data Todo.

#### Struktur Proyek
Berikut adalah struktur dasar dari aplikasi kita:

src/

├── components/
│   ├── TodoList.js       // Komponen untuk menampilkan daftar todo
│   ├── AddTodo.js        // Komponen untuk menambahkan todo baru

├── App.js                // Komponen utama yang menyatukan semuanya
└── index.js              // File entry point yang menginisialisasi QueryClient

### Langkah Implementasi

#### 1. **Mengambil Data Todo Menggunakan `useQuery`**

Buat file `TodoList.js` di folder `components/` untuk mengambil dan menampilkan daftar todo dari API.

```jsx
// components/TodoList.js
import React from 'react';
import { useQuery } from 'react-query';
import axios from 'axios';

const fetchTodos = async () => {
  const response = await axios.get('https://jsonplaceholder.typicode.com/todos');
  return response.data;
};

function TodoList() {
  const { data, isLoading, isError, error } = useQuery('todos', fetchTodos);

  if (isLoading) return <div>Loading...</div>;
  if (isError) return <div>Error: {error.message}</div>;

  return (
    <div>
      <h1>Todo List</h1>
      <ul>
        {data.map(todo => (
          <li key={todo.id}>
            {todo.title} {todo.completed ? '(Completed)' : ''}
          </li>
        ))}
      </ul>
    </div>
  );
}
export default TodoList;

Penjelasan:
- **`useQuery('todos', fetchTodos)`**: Mengambil data dari API dengan key `'todos'`, yang mengidentifikasi request ini di cache.
- Jika query sedang loading, tampilkan **Loading**.
- Jika ada error, tampilkan pesan error.
- Jika sukses, tampilkan daftar todo.

#### 2. **Menambahkan Todo Baru Menggunakan `useMutation`**

Selanjutnya, buat file `AddTodo.js` di folder `components/`. Komponen ini akan memungkinkan pengguna menambahkan todo baru menggunakan `useMutation`.

```jsx
// components/AddTodo.js
import React, { useState } from 'react';
import { useMutation, useQueryClient } from 'react-query';
import axios from 'axios';

const addTodo = async (newTodo) => {
  const response = await axios.post('https://jsonplaceholder.typicode.com/todos', newTodo);
  return response.data;
};

function AddTodo() {
  const [title, setTitle] = useState('');
  const queryClient = useQueryClient();

  const mutation = useMutation(addTodo, {
    onSuccess: () => {
      // Invalidate and refetch the 'todos' query to update the todo list
      queryClient.invalidateQueries('todos');
    },
  });
  const handleSubmit = (e) => {
    e.preventDefault();
    mutation.mutate({ title, completed: false });
    setTitle(''); // Reset input field
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={title}
        onChange={(e) => setTitle(e.target.value)}
        placeholder="Enter new todo"
        required
      />
      <button type="submit">Add Todo</button>

      {mutation.isLoading && <p>Adding todo...</p>}
      {mutation.isError && <p>Error: {mutation.error.message}</p>}
      {mutation.isSuccess && <p>Todo added successfully!</p>}
    </form>
  );
}
export default AddTodo;

Penjelasan:
- **`useMutation(addTodo)`**: Fungsi ini mengirimkan data baru ke API (menggunakan POST request) dan memperbarui cache menggunakan `queryClient.invalidateQueries('todos')` untuk memastikan bahwa daftar todo di-refresh setelah penambahan.
- Komponen ini juga menampilkan status loading, error, dan pesan sukses.

#### 3. **Menyatukan Komponen di `App.js`**

Sekarang kita gabungkan komponen-komponen tersebut di dalam `App.js`.

```jsx
// App.js
import React from 'react';
import TodoList from './components/TodoList';
import AddTodo from './components/AddTodo';

function App() {
  return (
    <div>
      <h1>Todo App with React Query</h1>
      <AddTodo />
      <TodoList />
    </div>
  );
}
export default App;

#### 4. **Konfigurasi QueryClient di `index.js`**

Konfigurasikan React Query di file `index.js` untuk menyediakan `QueryClientProvider` ke seluruh aplikasi.

```jsx
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { QueryClient, QueryClientProvider } from 'react-query';
import App from './App';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';

const queryClient = new QueryClient();

ReactDOM.render(
  <QueryClientProvider client={queryClient}>
    <App />
    <ReactQueryDevtools initialIsOpen={false} />
  </QueryClientProvider>,
  document.getElementById('root')
);

### Hasil Akhir
- Aplikasi akan menampilkan daftar todo yang diambil dari API di halaman utama.
- Pengguna dapat menambahkan todo baru dengan mengetikkan judul di input form dan mengklik tombol **Add Todo**.
- Setiap kali todo baru ditambahkan, daftar todo akan di-refresh secara otomatis untuk mencerminkan perubahan.

### Penjelasan Lebih Lanjut

- **useQuery**: Dipakai untuk pengambilan data secara efisien, mendukung caching, polling, dan re-fetching otomatis.
- **useMutation**: Dipakai untuk operasi mutasi data (POST, PUT, DELETE), dan memungkinkan pengelolaan perubahan data secara optimis atau asinkron.
- **invalidateQueries**: Digunakan setelah mutasi untuk memberitahukan React Query agar melakukan re-fetch pada query tertentu, sehingga data terbaru ditampilkan.
- **React Query Devtools**: Ini adalah tool yang berguna untuk memantau status query dan cache secara real-time, terutama untuk debugging.

### Tantangan dan Optimasi
- Kamu bisa mencoba mengimplementasikan fitur seperti **pagination** atau **infinite scrolling** pada daftar todo jika API mendukung.
- Jika API lambat, cobalah mengoptimalkan aplikasi dengan **optimistic updates** agar interaksi pengguna terasa lebih cepat.

Posting Komentar

Lebih baru Lebih lama

Formulir Kontak