I am using nextjs + typescript + react-query. Currently my app has an input that asks a user for a url, which is then used to fetch a list of github issues. Here are the simplified versions of the files:
url-form.tsx:
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { useIssues } from "@/hooks/use-issues";
import { Button } from "./ui/button";
import { Input } from "./ui/input";
const urlFormSchema = z.object({
url: z.string().url().includes("github.com")
});
type FormValues = z.infer<typeof urlFormSchema>;
export default function GithubUrlForm() {
const form = useForm<FormValues>({
resolver: zodResolver(urlFormSchema),
defaultValues: { url: "" }
});
const { data: issues, isLoading, isError } = useIssues(form.watch("url"));
const onSubmit = (data: FormValues) => {
console.log("Submitted URL:", data.url);
};
return (
<form onSubmit={form.handleSubmit(onSubmit)}>
<Input {...form.register("url")} placeholder="Enter GitHub repository URL" />
<Button type="submit" disabled={isLoading}>
{isLoading ? "Fetching..." : "Fetch Issues"}
</Button>
{isError && <p>Error fetching issues</p>}
{issues && <p>Fetched {issues.length} issues</p>}
</form>
);
}
page.tsx (Home):
import GithubUrlForm from "@/components/url-form";
import { QueryClient, HydrationBoundary, dehydrate } from "@tanstack/react-query";
export default function Home() {
const queryClient = new QueryClient();
return (
<main>
<HydrationBoundary state={dehydrate(queryClient)}>
<GithubUrlForm />
</HydrationBoundary>
</main>
);
}
use-issues.tsx:
import { useQuery } from "@tanstack/react-query";
import { Octokit } from "@octokit/rest";
const octokit = new Octokit();
const extractRepoInfo = (url: string) => {
const match = url.match(/github.com/([^/]+)/([^/]+)/);
if (!match) throw new Error("Invalid GitHub URL");
return { owner: match[1], repo: match[2] };
};
const fetchIssues = async (url: string) => {
const { owner, repo } = extractRepoInfo(url);
const { data } = await octokit.issues.listForRepo({ owner, repo, state: "open" });
return data;
};
export const useIssues = (url: string) => {
return useQuery({
queryKey: ["github-issues", url],
queryFn: () => fetchIssues(url),
enabled: url.trim() !== "",
});
};
Now what I want to do is access the list of issues in another component in order to render the list onto the UI. However, I would like to avoid bringing the url state upto the home component and passing it down into the new component as I want to keep the home component a server component. What is the next best way to access the data in a new component?