Skip to content

Instantly share code, notes, and snippets.

@MattyBalaam
Created February 28, 2024 08:20
Show Gist options
  • Save MattyBalaam/783406116eb859f4bae84bf90ba34ea8 to your computer and use it in GitHub Desktop.
Save MattyBalaam/783406116eb859f4bae84bf90ba34ea8 to your computer and use it in GitHub Desktop.
Remix: Attempt to get latest data from server with and without updating url in all cases
import { json, LoaderFunctionArgs } from "@remix-run/node";
import {
Form,
Link,
useFetcher,
useLoaderData,
useSearchParams,
} from "@remix-run/react";
import { useEffect, useState } from "react";
export const loader = async ({ request }: LoaderFunctionArgs) => {
const searchParams = new URL(request.url).searchParams;
const value = searchParams.get("search");
const color = searchParams.get("color");
console.log({ color, value });
return json({
time: new Date().toISOString().split("T").at(-1),
color,
});
};
export function useFetcherOrLoaderData<T>() {
const loaderData = useLoaderData<T>();
const fetcher = useFetcher<T>();
const [data, setData] = useState<typeof fetcher.data>(undefined);
useEffect(() => {
if (fetcher.state === "idle") {
console.log("update data from fetcher.data");
setData(fetcher.data);
}
}, [fetcher.state, fetcher.data]);
useEffect(() => {
console.log("update data from loaderData");
setData(loaderData);
}, [loaderData]);
return {
...fetcher,
data: data || loaderData,
};
}
const TestRoute = () => {
const fetcher = useFetcherOrLoaderData<typeof loader>();
const [searchParams] = useSearchParams();
return (
<div style={{ background: fetcher.data?.color || "" }}>
<Form>
<h1>{fetcher?.data?.time}</h1>
<input
name="search"
onChange={({ currentTarget: { value } }) => {
// send request, but do not update urls - we only want this when the form submits
fetcher.submit({ search: value, color: fetcher.data.color });
}}
/>
{/* hidden field to resubmit color value */}
<input name="color" type="hidden" value={fetcher.data.color || ""} />
<ul>
{["red", "green", "lightgrey", ""].map((color) => {
const newSearchParams = new URLSearchParams(searchParams);
// we need to create a link which includes the current search
newSearchParams.set("color", color);
return (
<li key={color}>
<Link to={`/?${newSearchParams.toString()}`}>
{color || "default"}
</Link>
</li>
);
})}
</ul>
</Form>
</div>
);
};
export default TestRoute;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment