It is pre built component offer by remix to make application more optimistic.
Imagine you are fetching a user's name from an API, and you want to display it once the data is resolved. Here's how you can use <Await>
with <Suspense>
to achieve this:
import React, { Suspense } from "react";
import { Await } from "@remix-run/react";
// Simulate a promise to fetch user data
const fetchUserName = new Promise((resolve) => {
setTimeout(() => {
resolve("Abhay");
}, 2000); // Resolves after 2 seconds
});
export default function App() {
return (
<div>
<h1>User Data</h1>
<Suspense fallback={<div>Loading...</div>}>
<Await resolve={fetchUserName}>
{(userName) => <p>Welcome, {userName}!</p>}
</Await>
</Suspense>
</div>
);
}
This built in component offers built-in onsubmit automatically submit content through action
and loader
, automatically handles file uploads and define your http
method and it also offer pending state.
import { Form, useLoaderData } from "@remix-run/react";
import { json } from "@remix-run/node";
export const loader = async ({ request }) => {
const url = new URL(request.url);
const name = url.searchParams.get("name"); // Get query parameter for the GET form
return json({ name });
};
export const action = async ({ request }) => {
const formData = await request.formData();
const file = formData.get("file");
const name = formData.get("name");
if (file) {
// Handle file upload
console.log(`Uploaded file: ${file.name}`);
}
if (name) {
// Handle form submission
return json({ message: `Hello, ${name}!` });
}
return json({ message: "No valid data received." });
};
export default function Index() {
const { name } = useLoaderData();
return (
<div>
<h1>Remix Form Examples</h1>
{/* POST Form Example */}
<section>
<h2>Submit Your Name (POST)</h2>
<Form method="post">
<label>
Name: <input type="text" name="name" />
</label>
<button type="submit">Submit</button>
</Form>
</section>
{/* GET Form Example */}
<section>
<h2>Search User (GET)</h2>
<Form method="get">
<label>
Name: <input type="text" name="name" />
</label>
<button type="submit">Search</button>
</Form>
{name && <p>Result: {name}</p>}
</section>
{/* File Upload Example */}
<section>
<h2>Upload a File</h2>
<Form method="post" encType="multipart/form-data">
<label>
File: <input type="file" name="file" />
</label>
<button type="submit">Upload</button>
</Form>
</section>
</div>
);
}
Its also pre-built in react as well as remix, extension of anchor tag
.
import { Link } from "@remix-run/react";
<Link to="/dashboard">Dashboard</Link>;
export const link = () => {
return [ { rel:'canonical', herf:'/post/389327832' } ]
}
This component is generally used only in root.tsx
file as all link tag present under links component.
import { Links } from "@remix-run/react";
export const links = () => [
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' },
{
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap',
},
{
rel: 'stylesheet',
href: 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-okaidia.min.css',
},
{
rel: 'icon',
type: "image/x-icon",
href: './favicon.ico',
},
]
export default function Root() {
return (
<html>
<head>
<Links />
</head>
<body></body>
</html>
);
}
This component generally connencts your app to Remix asset server and automatically renders the file content changed and save it in development environment. In production it renders null
.
import { LiveReload } from "@remix-run/react";
export default function Root() {
return (
<html>
<head />
<body>
<LiveReload />
</body>
</html>
);
}
This component same does the links component as it renders all the meta tags under one roof.
import { Meta } from "@remix-run/react";
export default function Root() {
return (
<html>
<head>
<Meta />
</head>
<body></body>
</html>
);
}
export const meta = () => {
return [
{ title: "New Remix App" },
{ name: "description", content: "Welcome to Remix!" },
];
};