---
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

Karena mesin `json-eval-rs` dibangun di atas arsitektur WebAssembly, file `.wasm` wajib ditarik lewat eksekusi impor asinkronus ke dalam browser sebelum kamu memanggil proses uji evaluasinya.

## 1. Instalasi

Instal API web core dan target bundler:

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

## 2. Membuat Custom Hook

Pola yang umum digunakan dalam arsitektur komponen React untuk menyembunyikan proses kompleks pemuatan WASM adalah dengan membungkus logicnya menggunakan Custom Hook.

```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.
