Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor code to send less data and revalidate data properly #1

Merged
merged 2 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 15 additions & 21 deletions app/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
import { Link, useLocation, useLoaderData } from "@remix-run/react"
import { LoaderFunctionArgs, json } from "@remix-run/node";

export const loader = async ({
params,
}: LoaderFunctionArgs) => {
const lang = params.lang
return json({ lang });
};
schabibi1 marked this conversation as resolved.
Show resolved Hide resolved
import { Link, useLocation, useParams } from "@remix-run/react";
import { getLang } from "~/utils";

export default function Header() {
let { lang } = useLoaderData<typeof loader>();
console.log("LANG: ", lang);

const location = useLocation();
const locationEntries = Object.entries(location)
const pathname = locationEntries[0]
const enPathname = pathname[1].includes("/ja") ? pathname[1].replace("/ja", "") : pathname[1]
const { pathname } = useLocation();
const params = useParams();
const lang = getLang(params);

return (
<div id="header">
<h1>{lang === "ja" ? `Optional Segments デモ` : `Optional Segments Example`}</h1>
<h1>
{lang === "ja" ? `Optional Segments デモ` : `Optional Segments Example`}
</h1>
<nav>
<Link to={`${enPathname}`}>🇺🇸</Link>
<Link to={`${lang = "ja"}${location.pathname}`}>🇯🇵</Link>
{lang === "ja" ? (
<Link to={pathname.replace(/^\/ja/, "")}>🇺🇸</Link>
) : (
<Link to={`/ja${pathname}`}>🇯🇵</Link>
)}
schabibi1 marked this conversation as resolved.
Show resolved Hide resolved
</nav>
</div>
)
}
);
}
49 changes: 6 additions & 43 deletions app/root.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,23 @@
import { json, LinksFunction, LoaderFunctionArgs } from "@remix-run/node";
import { LinksFunction } from "@remix-run/node";
import {
Link,
Links,
LiveReload,
Meta,
Outlet,
Scripts,
ScrollRestoration,
useLoaderData,
useParams,
} from "@remix-run/react";
import appStylesHref from "./app.css";
import { getContacts } from "./data";
import Header from "./components/Header";
import { getLang } from "./utils";

export const links: LinksFunction = () => [
{ rel: "stylesheet", href: appStylesHref },
];

export const loader = async ({
params,
}: LoaderFunctionArgs) => {
const fullContact = await getContacts();
const lang = params.lang
return json({ fullContact, lang });
};

export default function App() {
const { fullContact, lang } = useLoaderData<typeof loader>();
const params = useParams();
const lang = getLang(params);

return (
<html lang={lang}>
Expand All @@ -37,35 +28,7 @@ export default function App() {
<Links />
</head>
<body>
<Header />
<div id="wrapper">
<div id="sidebar">
<h1>{lang === "ja" ? `Remix コンタクト` : `Remix Contacts`}</h1>
<nav>
{fullContact.length ? (
<ul>
{fullContact.map((contact) => {
return (
<li key={contact.id}>
<Link to={`contacts/${contact.id}`}>
{lang === "ja" ? contact.details?.ja?.first : contact.details?.en?.first} {lang === "ja" ? contact.details?.ja?.last : contact.details?.en?.last}
</Link>
</li>
)
})}
</ul>
) : (
<p>
<i>No contacts</i>
</p>
)}
</nav>
</div>
<div id="detail">
<Outlet />
</div>
</div>

<Outlet />
<ScrollRestoration />
<Scripts />
<LiveReload />
Expand Down
42 changes: 13 additions & 29 deletions app/routes/($lang).contacts.$contactId.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,57 +3,41 @@ import { useLoaderData } from "@remix-run/react";
import { getContact } from "../data";
import type { LoaderFunctionArgs } from "@remix-run/node";
import invariant from "tiny-invariant";
import { getLang } from "~/utils";

export const loader = async ({
params,
}: LoaderFunctionArgs) => {
export const loader = async ({ params }: LoaderFunctionArgs) => {
invariant(params.contactId, "Missing contactId param");
const lang = getLang(params);
const singleContact = await getContact(params.contactId);
const lang = params.lang

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

const { details, ...contact } = singleContact;
return json({ contact, lang, details });
const { avatar, twitter, notes, details } = singleContact;
const name = `${details?.[lang]?.first} ${details?.[lang]?.last}`;
return json({ avatar, twitter, notes, name });
schabibi1 marked this conversation as resolved.
Show resolved Hide resolved
};

export default function Contact() {
const { contact, details, lang } = useLoaderData<typeof loader>();
const { avatar, twitter, notes, name } = useLoaderData<typeof loader>();
return (
<div id="contact">
<div>
<img
alt={`${details?.en?.first} ${details?.en?.last} avatar`}
key={contact.avatar}
src={contact.avatar}
/>
<img alt={`${name} avatar`} key={avatar} src={avatar} />
</div>

<div>
<h1>
{details?.ja?.first || details?.ja?.last || details?.en?.first || details?.en?.last ? (
<>
{lang === "ja" ? `${details?.ja?.first} ${details?.ja?.last}` : `${details?.en?.first} ${details?.en?.last}`}
</>
) : (
<i>No Name</i>
)}
</h1>
<h1>{name}</h1>

{contact.twitter ? (
{twitter ? (
<p>
<a
href={`https://twitter.com/${contact.twitter}`}
>
{contact.twitter}
</a>
<a href={`https://twitter.com/${twitter}`}>{twitter}</a>
</p>
) : null}

{contact.notes ? <p>{contact.notes}</p> : null}
{notes ? <p>{notes}</p> : null}
</div>
</div>
);
}
}
52 changes: 52 additions & 0 deletions app/routes/($lang).contacts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { LoaderFunctionArgs, json } from "@remix-run/node";
import { Link, Outlet, useLoaderData } from "@remix-run/react";
import Header from "~/components/Header";
import { getContacts } from "~/data";
import { getLang } from "~/utils";

export const loader = async ({ params }: LoaderFunctionArgs) => {
const fullContact = await getContacts();
const lang = getLang(params);

const contacts = fullContact.map((contact) => ({
id: contact.id,
name: `${contact.details?.[lang]?.first} ${contact.details?.[lang]?.last}`,
}));

return json({ contacts, lang });
};
schabibi1 marked this conversation as resolved.
Show resolved Hide resolved

export default function ContactsLayout() {
const { contacts, lang } = useLoaderData<typeof loader>();

return (
<>
<Header />
<div id="wrapper">
<div id="sidebar">
<h1>{lang === "ja" ? `Remix コンタクト` : `Remix Contacts`}</h1>
<nav>
{contacts.length ? (
<ul>
{contacts.map(({ id, name }) => {
return (
<li key={id}>
<Link to={`${id}`}>{name}</Link>
</li>
);
})}
</ul>
) : (
<p>
<i>No contacts</i>
</p>
)}
</nav>
</div>
<div id="detail">
<Outlet />
</div>
</div>
</>
);
}
5 changes: 5 additions & 0 deletions app/routes/_index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { redirect } from "@remix-run/node";

export function loader() {
return redirect("/contacts");
}
9 changes: 9 additions & 0 deletions app/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Params } from "@remix-run/react";

export function getLang(params: Params<string>) {
const lang = params.lang ?? "en";
if (lang !== "ja" && lang !== "en") {
throw new Error(`Invalid language ${lang}`);
}
return lang;
}