Komponen Server React

'use server' digunakan dengan Komponen Server React.

'use server' menandai fungsi-fungsi sisi server yang dapat dipanggil dari kode sisi klien.


Referensi

'use server'

Tambahkan 'use server' di bagian atas fungsi async untuk menandai bahwa fungsi tersebut dapat dipanggil oleh klien. Kami menyebut fungsi-fungsi ini sebagai Fungsi Server.

async function addToCart(data) {
'use server';
// ...
}

Saat memanggil Fungsi Server dari klien, 'use server' akan melakukan permintaan jaringan (network request) ke server dan menyertakan salinan ter-serialisasi dari setiap argumen yang dikirim. Jika Fungsi Server mengembalikan sebuah nilai, nilai tersebut akan di-serialisasi dan dikembalikan ke klien.

Daripada menandai fungsi satu per satu dengan 'use server', Anda bisa menambahkan direktif ini di bagian paling atas file untuk menandai semua fungsi yang diekspor dalam file tersebut sebagai Fungsi Server yang dapat digunakan di mana saja, termasuk diimpor dalam kode klien.

Catatan penting

  • 'use server' harus berada di paling atas dari fungsi atau modul; di atas kode-kode lain termasuk impor (tidak apa-apa menambahkan komentar di atas direktif). Direktif harus diapit tanda kutip tunggal atau ganda, bukan tanda kutip terbalik.
  • 'use server' hanya dapat digunakan dalam file sisi server. Fungsi Server yang dihasilkan dapat diteruskan ke Komponen Klien melalui props. Lihat tipe untuk serialisasi yang didukung.
  • Untuk mengimpor Fungsi Server dari kode klien, direktif harus digunakan pada tingkat modul.
  • Karena panggilan jaringan (network call) yang mendasarinya selalu asinkron, 'use server' hanya dapat digunakan pada fungsi async.
  • Selalu perlakukan argumen ke Fungsi Server sebagai masukan yang tidak tepercaya dan otorisasi setiap mutasi. Lihat pertimbangan keamanan.
  • Fungsi Server harus dipanggil dalam Transisi. Fungsi Server yang diteruskan ke <form action> atau formAction akan secara otomatis dipanggil dalam transisi.
  • Fungsi Server dirancang untuk mutasi yang memperbarui state di sisi server; fungsi ini tidak direkomendasikan untuk pengambilan data. Oleh karena itu, framework yang menerapkan Fungsi Server biasanya memproses satu aksi dalam satu waktu dan tidak memiliki cara untuk melakukan caching terhadap nilai yang dikembalikan.

Pertimbangan keamanan

Argumen untuk Fungsi Server sepenuhnya dikendalikan oleh klien. Demi keamanan, selalu perlakukan argumen tersebut sebagai masukan yang tidak tepercaya, dan pastikan untuk memvalidasi serta menyaring argumen sesuai kebutuhan.

Dalam setiap Funsi Server, pastikan untuk memvalidasi bahwa pengguna yang sedang masuk diizinkan untuk melakukan aksi tersebut.

Dalam Pengembangan

Untuk mencegah pengiriman data sensitif dari Fungsi Server, terdapat API taint eksperimental untuk mencegah nilai dan objek unik diteruskan ke kode klien.

Lihat experimental_taintUniqueValue dan experimental_taintObjectReference.

Argumen yang dapat diserialisasi dan nilai kembalian

Karena kode klien memanggil Fungsi Server melalui jaringan, setiap argumen yang dikirim harus dapat diserialisasi.

Berikut adalah tipe data yang didukung untuk argumen Fungsi Server:

Yang tidak didukung, antara lain:

  • Elemen React, atau JSX
  • Fungsi komponen atau fungsi lainnya yang bukan Fungsi Server
  • Kelas
  • Objek yang merupakan instance dari kelas apa pun (selain bawaan seperti yang telah disebutkan) atau objek dengan null prototype
  • Simbol yang tidak didaftarkan secara global, misalnya Symbol('my new symbol')
  • Event dari event handler

Nilai kembali yang dapat diserialisasi mengikuti aturan yang sama dengan properti yang bisa diserialisasi untuk Komponen Klien yang menjadi pembatas.

Penggunaan

Server Functions in forms

Fungsi Server biasanya digunakan untuk memanggil fungsi di server yang mengubah data. Di peramban, pengguna umumnya mengirimkan perubahan data lewat elemen formulir HTML. Dengan komponen server React, React kini mendukung Fungsi Server secara langsung di dalam formulir.

Contoh di bawah ini menunjukkan formulir yang meminta nama pengguna.

// App.js

async function requestUsername(formData) {
'use server';
const username = formData.get('username');
// ...
}

export default function App() {
return (
<form action={requestUsername}>
<input type="text" name="username" />
<button type="submit">Meminta</button>
</form>
);
}

Dalam contoh ini, requestUsername adalah sebuah Fungsi Server yang diteruskan ke sebuah formulir <form>. Ketika pengguna mengirim formulir ini, akan ada permintaan jaringan ke fungsi server requestUsername. Saat memanggil Fungsi Server lewat formulir, React akan mengirimkan FormData dari formulir sebagai argumen pertama ke Fungsi Server tersebut.

Dengan meneruskan Fungsi Server ke action formulir, React bisa meningkatkan fungsionalitas formulir secara progresif. Artinya, formulir tetap bisa dikirimkan meskipun bundel JavaScript belum dimuat sepenuhnya.

Menangani nilai kembali dari formulir

Dalam formulir diatas, ada kemungkinan nama pengguna yang diminta tidak tersedia. requestUsername harus memberi tahu apakah permintaan tersebut berhasil atau gagal.

Untuk memperbarui antarmuka pengguna berdasarkan hasil dari Fungsi Server sambil tetap mendukung peningkatan progresif, gunakan useActionState.

// requestUsername.js
'use server';

export default async function requestUsername(formData) {
const username = formData.get('username');
if (canRequest(username)) {
// ...
return 'successful';
}
return 'failed';
}
// UsernameForm.js
'use client';

import { useActionState } from 'react';
import requestUsername from './requestUsername';

function UsernameForm() {
const [state, action] = useActionState(requestUsername, null, 'n/a');

return (
<>
<form action={action}>
<input type="text" name="username" />
<button type="submit">Meminta</button>
</form>
<p>Respon dari pengiriman terakhir: {state}</p>
</>
);
}

Perlu diingat bahwa seperti Hook lainnya, useActionState hanya bisa dipanggil di kode klien.

Memanggil sebuah Fungsi Server dari luar formulir <form>

Fungsi Server adalah endpoint di sisi server dan bisa dipanggil dari mana saja di dalam kode klien.

Jika Anda menggunakan Fungsi Server di luar formulir, panggillah Fungsi Server tersebut di dalam sebuah Transisi, yang memungkinkan Anda menampilkan indikator pemuatan, melakukan pembaruan status optimistis, dan menangani error yang tidak terduga. Formulir akan secara otomatis membungkus Fungsi Server di dalam transisi.

import incrementLike from './actions';
import { useState, useTransition } from 'react';

function LikeButton() {
const [isPending, startTransition] = useTransition();
const [likeCount, setLikeCount] = useState(0);

const onClick = () => {
startTransition(async () => {
const currentCount = await incrementLike();
setLikeCount(currentCount);
});
};

return (
<>
<p>Total Suka: {likeCount}</p>
<button onClick={onClick} disabled={isPending}>Suka</button>;
</>
);
}
// actions.js
'use server';

let likeCount = 0;
export default async function incrementLike() {
likeCount++;
return likeCount;
}

Untuk mendapatkan hasil dari Fungsi Server, Anda perlu menunggu promise-nya dengan menggunakan await.