React Server Components: wyjaśnienie use client, Server Actions i Suspense | We.Inc
React Server Components prostym językiem: diagram granic, zasady "use client", pobieranie danych, server actions dla formularzy z useActionState, streaming z Suspense i rozwiązania częstych błędów.
React Server Components: wyjaśnienie
React Server Components renderują się na serwerze i wysyłają do przeglądarki gotowy UI, a nie swój JavaScript. Mogą bezpośrednio czekać na dane (await) i używać sekretów. Wszystko, co interaktywne, trafia do Client Component, czyli pliku zaczynającego się od "use client". Formularze mogą wywoływać funkcje serwerowe oznaczone "use server", a Suspense dosyła wolne części później w strumieniu.
Trzy dyrektywy i hooki, których potrzebujesz
Napisz
Znaczenie
(nic)
Server Component w Next.js App Router
"use client"
Ten plik i jego importy działają także w przeglądarce
"use server"
Te eksportowane funkcje po wywołaniu działają na serwerze
<Suspense>
Pokaż tu fallback, dopóki ta część się wczytuje
Zacznij od diagramu: niebieskie pola zostają na serwerze, pomarańczowe trafiają także do przeglądarki. Potem skopiuj wzorce dla danych, formularzy i streamingu, a gdy build zgłasza problem, skorzystaj z tabeli błędów.
Domyślnie zostawiaj komponenty jako Server Components.
Pobieraj dane w asynchronicznych Server Components, blisko miejsca, w którym są wyświetlane.
Dodawaj "use client" tylko do małych części, które potrzebują stanu lub obsługi zdarzeń.
Używaj funkcji serwerowych do formularzy i mutacji, z useActionState do informacji zwrotnej.
Owiń wolne części w Suspense lub dodaj loading.tsx, aby strona pojawiła się szybko.
Przesuwaj "use client" jak najniżej w drzewie; granica blisko korzenia sprawia, że cała aplikacja znów działa po stronie klienta.
Waliduj każde wejście funkcji serwerowej. To publiczny endpoint, nawet jeśli wywołuje go tylko Twój formularz.
Sprawdzaj, kim jest użytkownik, wewnątrz każdej funkcji serwerowej, a nie tylko na stronie wyświetlającej formularz.
Przekazuj Server Components do Client Components jako children zamiast je importować.
Unikaj kaskad żądań: uruchamiaj niezależne pobierania razem za pomocą Promise.all.
Najczęściej zadawane pytania
Czy Server Components to to samo co renderowanie po stronie serwera?
Nie. Renderowanie po stronie serwera zamienia dowolny komponent w HTML przy pierwszym wczytaniu i nadal wysyła jego JavaScript. Server Component nigdy nie wysyła swojego JavaScriptu; wysyłany jest tylko jego wynik. Client Components też są renderowane na serwerze przy pierwszym wczytaniu.
Czy potrzebuję Next.js, aby używać Server Components?
Wymagają frameworka lub bundlera, który je obsługuje. Najpowszechniej używany jest Next.js App Router; obsługuje je też kilka innych, na przykład Waku.
Czy Client Component może importować Server Component?
Nie, import z pliku klienckiego wciąga moduł do bundla klienta. Zamiast tego przekaż Server Component jako children lub inny prop z nadrzędnego Server Component.
Jaka jest różnica między server actions a funkcjami serwerowymi?
React nazywa dziś każdą funkcję oznaczoną "use server" funkcją serwerową. Gdy jest używana jako akcja formularza lub wywoływana wewnątrz transition, często nazywa się ją server action. Next.js jako pierwszy użył terminu server actions.
Czy useActionState działa bez JavaScriptu?
Formularz nadal wysyła dane do funkcji serwerowej przed hydratacją, więc się wysyła. Stan oczekiwania i komunikat w treści wymagają JavaScriptu, więc zadbaj o to, aby serwer w obu przypadkach zwracał użyteczną stronę.
Dlaczego ten model pomaga stronie internetowej
Większość strony marketingowej lub z treścią nigdy się nie zmienia po wyrenderowaniu: nagłówki, tekst, obrazy, karty produktów. Jako Server Components nie kosztują w ogóle JavaScriptu, co zostawia główny wątek wolny dla kilku interaktywnych części i zwykle poprawia Interaction to Next Paint.
Lista kontrolna bezpieczeństwa funkcji serwerowych
Traktuj każdą funkcję "use server" jak trasę API: sprawdź sesję, zwaliduj wejście schematem, sprawdź, czy użytkownik może zmienić dany rekord, i zwracaj tylko to, czego potrzebuje klient. Nigdy nie zwracaj wierszy bazy danych z polami, których użytkownik nie powinien widzieć.
Co gdzie działa
Gdzie może działać każdy element
Potrzebujesz
Server Component
Client Component
Odczytać bazę danych lub sekretny klucz API
Tak
Nie (ujawniłoby to sekret)
Użyć await na danych bezpośrednio w komponencie
Tak (komponent async)
Nie
useState, useEffect, useReducer
Nie
Tak
onClick, onChange i inne handlery
Nie
Tak
window, localStorage, API przeglądarki
Nie
Tak, po zamontowaniu
Nie wysyłać żadnego JavaScriptu komponentu
Tak
Nie
Renderować komponent drugiego rodzaju
Tak, renderuje Client Components
Tylko Server Components przekazane jako children lub propsy
Server Components i Client Components
Server Component odczytujący dane
W App Router komponenty są Server Components, chyba że oznaczono je inaczej. Mogą być async i komunikować się bezpośrednio z bazą danych; nic z tego kodu nie trafia do przeglądarki.
Client Component do interakcji
"use client" na samej górze oznacza granicę: ten plik i wszystko, co importuje, jest bundlowane dla przeglądarki. Utrzymuj te pliki małe i przesuwaj je do liści drzewa.
Przekazywanie Server Component przez Client Component
Client Component nie może importować Server Component, ale może otrzymać go jako children. Serwer renderuje go najpierw, a klient tylko umieszcza wynik.
Nie wypuść przypadkiem sekretów do przeglądarki
Zaimportowanie pakietu server-only sprawia, że build się nie powiedzie, jeśli jakiś plik kliencki kiedykolwiek zaimportuje ten moduł, więc klucz API nie wycieknie przez nieostrożny import.
Funkcje serwerowe dla formularzy
Formularz wysyłający dane do funkcji serwerowej
"use server" zamienia funkcję async w endpoint, który formularz może wywołać. Formularz działa przed wczytaniem JavaScriptu, bo to prawdziwe wysłanie formularza.
Stan oczekiwania i wyniku z useActionState
useActionState (React 19) owija funkcję serwerową i daje Ci jej ostatni wynik oraz flagę oczekiwania, więc przycisk może wyświetlić Wysyłanie, a komunikat może się pojawić bez dodatkowego stanu.
Odśwież dane strony po zmianie
Po mutacji powiedz Next.js, dane której ścieżki są nieaktualne, aby następne renderowanie pokazało zmianę.
Streaming z Suspense
Strumieniuj wolną część z Suspense
Owiń wolny Server Component w Suspense. Reszta strony jest wysyłana od razu z fallbackiem na miejscu, a wolna część dopływa w strumieniu, gdy nadejdą jej dane.
loading.tsx dla całej trasy
Plik loading.tsx obok page.tsx sam owija tę stronę w granicę Suspense, więc nawigacja pokazuje go od razu, podczas gdy dane strony się wczytują.
Uruchamiaj żądania razem
Czekanie na jedno pobranie po drugim w Server Component sumuje ich czasy. Uruchom je jednocześnie i poczekaj na oba.
Błędy, które napotkasz
Częste błędy i ich rozwiązania
Co widzisz
Przyczyna
Rozwiązanie
Hook taki jak useState działa tylko w Client Component
Hook w pliku bez "use client"
Przenieś interaktywną część do osobnego pliku zaczynającego się od "use client"
Handlerów zdarzeń nie można przekazywać do propsów Client Component
onClick przekazany z Server Component
Umieść handler wewnątrz Client Component lub przekaż zamiast niego funkcję serwerową
Funkcji nie można przekazywać bezpośrednio do Client Components
Zwykła funkcja przekazana jako prop przez granicę
Oznacz ją "use server", jeśli ma działać na serwerze, lub zdefiniuj ją w pliku klienckim
Do Client Components można przekazywać tylko zwykłe obiekty
Instancje klas, takie jak modele pełne obiektów Date lub Mapy, wysłane jako propsy
Przekazuj zwykłe dane (ciągi znaków, liczby, tablice, zwykłe obiekty)
window is not defined
API przeglądarki użyte podczas renderowania na serwerze
Odczytaj je wewnątrz useEffect lub najpierw sprawdź typeof window
Niezgodność hydratacji
Serwer i przeglądarka wyrenderowały inny tekst (daty, losowe wartości)
Renderuj zmienną część tylko po stronie klienta lub przekaż wartość z serwera
Kod asynchroniczny to dla Ciebie nowość? Zacznij od