lastik next dokümantasyonu aslında gayet sade.
CSR
ve SSR
konularına cok takılmanıza gerek yok bence. Next ve React bu işi senin için hallediyor. Bilmen gereken nokta şu. Aksini belirtmediğin sürece bütün komponentler server componenti. Eğer "use client"
ile süslenmişse client componenti. Eğer bir client componenti server componenti import ediyorsa oda client componenti oluyor.
server componentlerini şöyle düşün. bu node serverinda plain html olarak render ediliyor ve response içinde bu html dönüyor. yani burda window objesi yok. Dolayısı ile client javascriptide yok. Bundan dolayı event listeners
ve useEffect
useState
gibi client side hooklarıda server componentlerin de çalışmıyor.
Eğer component use client
ile süslenmiş ise. bu component serverdan dönen htlm'e yerleştirilmek yerine yerleşiceği yer işaretleniyor. js kodları browsera gidince bu component browser tarafında render edilip bu belirlenen yere yerleştiriliyor.
Veri çekme konusuna gelince
server tarafında direk istediğiniz veriyi çekebilirsiniz. Client tarafında ise fetch api veya yeni gelen server actions kullanabililirsiniz. Actionları client componentlerine props olarak gecebiliyoruz bu arada
En basit yol olarak server componentlerinde dogrudan herhangi serverside resource çağırabilirsin
export default async function Page() {
const data = await database.find(....) // bu satir hic bir zaman client tarafinda expose olmaz
return (
<>
{data}
...server side html...
</>
)
}
next ile iki çeşit endpoint oluşturulabiliyor;
- bunlardan birincisi bildiğin üzere page.{tsx|jsx}
- ikincisi ise route.{ts|js} burdada rest metodlarina karsilik gelen handlerlari (get, post, put, patch ...) export edebiliyorsun.
örnek .../src/app/api/users/route.ts
export async function GET(request: Request) {}
Mesela bu endpoint'e herhangi bir client componentinde fetch isteği atabilirsiniz.fetch("/api/users")
https://nextjs.org/docs/app/building-your-application/routing/route-handlers
not: yalnız her dizinde bunlardan sadece biri olabilir. Bunun sebebi next app router dizine göre route oluşturuyor.
asıl kullanılması gereken yöntem ise ( next bu şekilde öneriyor ) server actions. Burda next'in RPC
(Remote Procedure Calling) bazlı bir yaklaşımı var. Serverdaki action olarak belirlenmiş bir metodu client tarafında çağırmanıza olanak ( kısmen ) tanıyor.
iki şekilde server action oluşturabiliyoruz.
- birincisi layout veya page içinde herhangi bir asenkron methodu
"use server"
ile süsleyerek
page.tsx
export default async function Page() {
async function HelloWorldAction() {
"use server"
console.log("Hello world")
}
return (
<> <ClientComponent action={HelloWorldAction} /> </>
)
}
clientComponent.tsx
export default function ClientComponent({helloWorldAction}: { helloWorldAction: ()=> void }) {
return (
<button onClick={() => helloWorldAction()}> Tikla </button>
)
}
burdaki butona tıklandığında Hello world
cıktısını browser consolu yerine server consolunda görüyor olman lazım. Bu durumu o metodun server tarafında çalıştığının kanıtı olarak görebilirsin.
- ikinci yöntem ise. herhangi
ts
veya js
dosyasının en başını "use server"
ile süslemek. Burdan export edilen asenkron metodlar next tarafından server action olarak ele alınacak.
ister bunu componentlere props olarak geç ister doğrudan import et. iki şekildede kullanabilirsin.
Server actionlari kullanmanın diğer avantajlarından biride. Client side js olmadanda, native form submission olarak çalışabiliyor olması. Buda server componentlerinde kullanabilmemiz anlamına geliyor.
"use server"
export const LoginAction = async (form: FormData) => {
const { email, password }= object.fromEntries(form)
// email ve password ile bir şeyler yap
....
}
loginForm.tsx
import { LoginAction } from "./loginAction"
export default function LoginForm() {
return (
<form action={LoginAction}>
<input type="email" name="email" id="" />
<input type="password" name="password" id="" />
<button type="submit">Giriş</button>
</form>
)
}
edit: suspense ve server actionlarin ile verdiğim örneklerin kodları
https://github.com/KerimCETINBAS/nextExample