0

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:

"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>
  );
}

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),
  });
};

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?

2
  • Your options are typically context or state management (eg redux). The former can also run into server / client issues though
    – Phil
    Commented Jul 2 at 5:47
  • 1
    How about passing url as a searchParams so that you can retrive it from url? I think you can use 'enable' property with it, so that you don't need to retrieve url from client state. Commented Jul 2 at 6:32

0