Created
December 24, 2025 04:22
-
-
Save saturngod/61cab920ddb56ec4cbd52727070769f9 to your computer and use it in GitHub Desktop.
tanstack stack example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { Button } from '@/components/ui/button' | |
| import { Input } from '@/components/ui/input' | |
| import { createFileRoute, useRouter } from '@tanstack/react-router' | |
| import { createServerFn } from '@tanstack/react-start' | |
| import { z } from 'zod' | |
| // --- 1. FAKE DATABASE (Global Array) --- | |
| // Server မရပ်မချင်း ဒီ variable က memory ထဲမှာ ကျန်နေပါလိမ့်မယ်။ | |
| // Real world မှာတော့ ဒါဟာ Database Table တစ်ခု ဖြစ်ပါလိမ့်မယ်။ | |
| declare global { | |
| var fakeDbPosts: string[] | undefined | |
| } | |
| if (!globalThis.fakeDbPosts) { | |
| globalThis.fakeDbPosts = ["Initial Post 1", "Initial Post 2"] | |
| } | |
| const fakeDbPosts = globalThis.fakeDbPosts! | |
| const postSchema = z.object({ | |
| title: z.string().min(1), | |
| }) | |
| type Post = z.infer<typeof postSchema> | |
| // --- 2. SERVER FUNCTIONS --- | |
| // POST (Data ထည့်မည်) | |
| const addPost = createServerFn({ method: 'POST' }) | |
| .inputValidator((data: Post) => postSchema.parse(data)) | |
| .handler(async ({ data }) => { | |
| console.log('Server: Adding new post ->', data.title) | |
| // Fake DB ထဲကို ထည့်လိုက်တယ် | |
| fakeDbPosts.push(data.title) | |
| console.log('Fake DB ->', fakeDbPosts) | |
| // Simulation Delay (DB ထဲထည့်သလို ကြာအောင်လုပ်ပြတာ) | |
| await new Promise((resolve) => setTimeout(resolve, 300)) | |
| return { success: true } | |
| }) | |
| // GET (Data ပြန်ယူမည်) | |
| const getPosts = createServerFn({ method: 'GET' }).handler(async () => { | |
| console.log('Server: Fetching posts...') | |
| // ရှိသမျှ Data အကုန်ပြန်ပို့မယ် (အသစ်ထည့်ထားတာတွေရော) | |
| console.log('Fake Fetch DB ->', fakeDbPosts) | |
| return fakeDbPosts | |
| }) | |
| // --- 3. ROUTE & COMPONENT --- | |
| export const Route = createFileRoute('/detail/')({ | |
| // Page စတက်တာနဲ့ getPosts ကို ခေါ်ပြီး Data ဆွဲထားမယ် | |
| loader: async () => await getPosts(), | |
| component: RouteComponent, // RouteComponent ကို ခေါ်ပြီး ပြပေးမယ် | |
| }) | |
| function RouteComponent() { | |
| const posts = Route.useLoaderData() | |
| const router = useRouter() | |
| const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => { | |
| e.preventDefault() | |
| const form = e.currentTarget | |
| const formData = new FormData(form) | |
| const title = formData.get('title') as string | |
| if (!title) return | |
| // (A) Server ပေါ်မှာ Data သွားထည့် (Global Array ပြောင်းသွားပြီ) | |
| await addPost({ data: { title } }) | |
| form.reset() | |
| // (B) Data ဟောင်းသွားပြီ၊ အသစ်ပြန်ဆွဲပေးပါ (Re-fetch Loader) | |
| // ဒီကောင်အလုပ်လုပ်လိုက်တာနဲ့ 'getPosts' ကို နောက်တစ်ခေါက် ပြန်ခေါ်သွားတာပါ | |
| await router.invalidate() | |
| } | |
| return ( | |
| <div className="p-10 space-y-6 max-w-md mx-auto"> | |
| <h2 className="text-2xl font-bold">Fake DB Demo</h2> | |
| {/* List */} | |
| <div className="space-y-2 border p-4 rounded bg-slate-50"> | |
| {posts.map((post: string, index: number) => ( | |
| <div key={index} className="p-3 bg-white shadow-sm rounded border"> | |
| {post} | |
| </div> | |
| ))} | |
| {posts.length === 0 && <p>No posts yet.</p>} | |
| </div> | |
| {/* Form */} | |
| <form onSubmit={handleSubmit} className="flex gap-2"> | |
| <Input name="title" placeholder="Type something..." required /> | |
| <Button type="submit">Add</Button> | |
| </form> | |
| </div> | |
| ) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment