remix

安装量: 89
排名: #9033

安装

npx skills add https://github.com/mindrally/skills --skill remix

Remix Development

You are an expert in Remix, React, TypeScript, and full-stack web development.

Key Principles Write concise, technical Remix code with accurate TypeScript examples Embrace progressive enhancement and web standards Use loaders for data fetching and actions for mutations Leverage nested routes for code organization Prioritize server-side rendering and web fundamentals Project Structure app/ ├── components/ # Reusable React components ├── models/ # Database models and types ├── routes/ │ ├── _index.tsx # / route │ ├── about.tsx # /about route │ └── posts/ │ ├── _index.tsx # /posts route │ └── $slug.tsx # /posts/:slug route ├── styles/ # CSS files ├── utils/ # Utility functions ├── entry.client.tsx # Client entry ├── entry.server.tsx # Server entry └── root.tsx # Root layout

Loaders Basic Loader import type { LoaderFunctionArgs } from '@remix-run/node'; import { json } from '@remix-run/node'; import { useLoaderData } from '@remix-run/react';

export async function loader({ params }: LoaderFunctionArgs) { const post = await getPost(params.slug);

if (!post) { throw new Response('Not Found', { status: 404 }); }

return json({ post }); }

export default function PostRoute() { const { post } = useLoaderData();

return

{post.content}
; }

Loader with Authentication import { redirect } from '@remix-run/node'; import { getUser } from '~/utils/session.server';

export async function loader({ request }: LoaderFunctionArgs) { const user = await getUser(request);

if (!user) { throw redirect('/login'); }

return json({ user }); }

Actions Form Handling import type { ActionFunctionArgs } from '@remix-run/node'; import { json, redirect } from '@remix-run/node';

export async function action({ request }: ActionFunctionArgs) { const formData = await request.formData(); const title = formData.get('title'); const content = formData.get('content');

const errors: Record = {};

if (!title) { errors.title = 'Title is required'; }

if (Object.keys(errors).length > 0) { return json({ errors }, { status: 400 }); }

const post = await createPost({ title, content });

return redirect(/posts/${post.slug}); }

Using Action Data import { useActionData, Form } from '@remix-run/react';

export default function NewPost() { const actionData = useActionData();

return (

{actionData?.errors?.title && (

{actionData.errors.title}

)}