Created
February 28, 2024 08:20
-
-
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
This file contains 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 { 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