---
title: 'React'
description: "Pelajari cara menggunakan JSONEval-Rs di aplikasi React standar (misal: yang dibuat dengan Vite atau Create React App)."
navigation:
  icon: 'i-simple-icons-react'
seo:
  title: 'React'
  description: "Pelajari cara menggunakan JSONEval-Rs di aplikasi React standar (misal: yang dibuat dengan Vite atau Create React App)."
---

# Menggunakan JSONEval-Rs di React

Panduan ini menjelaskan cara mengintegrasikan `json-eval-rs` secara efisien ke dalam aplikasi React standar.

Karena `json-eval-rs` menggunakan WebAssembly (WASM), tantangan utama di browser adalah memuat file biner WASM secara asinkron sebelum logika evaluasi bisa dijalankan.

## 1. Instalasi

Instal API web core dan target bundler:

```bash
yarn add @json-eval-rs/webcore @json-eval-rs/bundler
```

## 2. Membuat Custom Hook

Agar lebih mudah menggunakan evaluator di komponen React, praktik terbaiknya adalah memuatnya sekali saja secara asinkron menggunakan React Context dan Hook kustom, atau cukup di dalam satu komponen jika hanya dibutuhkan di sana.

Mari kita buat hook `useJSONEval` yang akan menginisialisasi instance tersebut.

```typescript
// useJSONEval.ts
import { useState, useEffect } from 'react';
import { JSONEval } from '@json-eval-rs/webcore';

export function useJSONEval(schema: any) {
  const [evaluator, setEvaluator] = useState<JSONEval | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    let instance: JSONEval | null = null;
    let isMounted = true;

    async function init() {
      try {
        // Impor modul bundler secara dinamis
        const wasmModule = await import('@json-eval-rs/bundler');
        
        if (isMounted) {
          instance = new JSONEval({
            schema: JSON.stringify(schema),
            wasmModule
          });
          setEvaluator(instance);
          setLoading(false);
        }
      } catch (err) {
        if (isMounted) {
          setError(err instanceof Error ? err : new Error(String(err)));
          setLoading(false);
        }
      }
    }

    init();

    return () => {
      isMounted = false;
      // SELALU hapus penggunaan memori (free)!
      if (instance) {
        instance.free();
      }
    };
  }, [schema]);

  return { evaluator, loading, error };
}
```

## 3. Menggunakan Evaluator di Komponen

Setelah hook selesai dibuat, kamu bisa membangun komponen yang melakukan evaluasi logika secara real-time saat pengguna mengetik.

```tsx
import React, { useState } from 'react';
import { useJSONEval } from './useJSONEval';

const schema = {
  type: "object",
  properties: {
    age: {
      rules: {
        minValue: { value: 18, message: "Kamu harus berumur 18 tahun ke atas untuk lanjut." }
      }
    }
  }
};

export function AgeValidator() {
  const { evaluator, loading, error } = useJSONEval(schema);
  const [age, setAge] = useState<string>('');
  const [validationResult, setValidationResult] = useState<any>(null);

  const validate = async (value: string) => {
    if (!evaluator) return;
    
    const parsedAge = parseInt(value, 10);
    const result = await evaluator.validate({
      data: JSON.stringify({ age: isNaN(parsedAge) ? 0 : parsedAge })
    });
    
    setValidationResult(result);
  };

  const handleAgeChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    setAge(value);
    validate(value);
  };

  if (loading) return <div>Memuat mesin evaluasi...</div>;
  if (error) return <div>Gagal memuat: {error.message}</div>;

  const hasError = validationResult?.has_error;

  return (
    <div>
      <h3>Validasi Umur</h3>
      <input 
        type="number" 
        value={age} 
        onChange={handleAgeChange}
        placeholder="Masukkan umurmu" 
      />
      
      {hasError && (
        <ul style={{ color: 'red' }}>
          {validationResult.errors.map((err: any, idx: number) => (
            <li key={idx}>{err.message}</li>
          ))}
        </ul>
      )}
      {!hasError && age !== '' && (
        <p style={{ color: 'green' }}>Kelihatannya bagus!</p>
      )}
    </div>
  );
}
```

### Hal Penting untuk React

1. **Manajemen Memori**: Perhatikan `instance.free()` di dalam fungsi pembersihan `useEffect`. Ini sangat krusial untuk mencegah kebocoran memori (memory leak) saat komponen dihapus (unmount) atau schema berubah.
2. **Impor Dinamis**: Kita melakukan impor secara dinamis pada `@json-eval-rs/bundler` karena pemuatan WebAssembly harus terjadi secara asinkron.
3. **Pembaruan Status**: Lakukan evaluasi setiap kali data pengguna berubah dan simpan hasilnya.
