T
TanStack15mo ago
realistic-cyan

How to use react query data in another component without moving state up?

I am using nextjs app router + 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:
"use client";

import { useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { useIssues } from "@/hooks/use-issues";
import { urlFormSchema } from "@/lib/schema";
//form imports

type FormValues = z.infer<typeof urlFormSchema>;

export default function GithubUrlForm() {
const [url, setUrl] = useState<string>("");

const form = useForm<FormValues>({
resolver: zodResolver(urlFormSchema),
defaultValues: { url: "" },
});

const { data: issues, error, isError, isLoading, isSuccess } = useIssues(url);

const onSubmit = (data: FormValues) => {
queryClient.removeQueries({ queryKey: ["github-issues"] });
setUrl(data.url);
};

return (
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
>
<div className="flex-grow">
<FormField
control={form.control}
name="url"
render={({ field }) => (
<FormItem className="w-full">
<FormControl>
<Input
placeholder="Enter your Github repository URL"
{...field}
/>
</FormControl>
</FormItem>
)}
/>
</div>

<Button type="submit" disabled={isLoading}>
{isLoading ? "Fetching..." : "Fetch Issues!"}
</Button>
</form>
</Form>
);
}
"use client";

import { useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { useIssues } from "@/hooks/use-issues";
import { urlFormSchema } from "@/lib/schema";
//form imports

type FormValues = z.infer<typeof urlFormSchema>;

export default function GithubUrlForm() {
const [url, setUrl] = useState<string>("");

const form = useForm<FormValues>({
resolver: zodResolver(urlFormSchema),
defaultValues: { url: "" },
});

const { data: issues, error, isError, isLoading, isSuccess } = useIssues(url);

const onSubmit = (data: FormValues) => {
queryClient.removeQueries({ queryKey: ["github-issues"] });
setUrl(data.url);
};

return (
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
>
<div className="flex-grow">
<FormField
control={form.control}
name="url"
render={({ field }) => (
<FormItem className="w-full">
<FormControl>
<Input
placeholder="Enter your Github repository URL"
{...field}
/>
</FormControl>
</FormItem>
)}
/>
</div>

<Button type="submit" disabled={isLoading}>
{isLoading ? "Fetching..." : "Fetch Issues!"}
</Button>
</form>
</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>
);
}
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) => {
// some regex
};

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),
});
};
import { useQuery } from "@tanstack/react-query";
import { Octokit } from "@octokit/rest";

const octokit = new Octokit();

const extractRepoInfo = (url: string) => {
// some regex
};

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),
});
};
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?
0 Replies
No replies yetBe the first to reply to this messageJoin

Did you find this page helpful?