Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When using useSearchParams from Nextjs and Remix with Select component causes multiple reenders. #1073

Closed
juliomuhlbauer opened this issue Dec 6, 2023 · 3 comments

Comments

@juliomuhlbauer
Copy link
Contributor

juliomuhlbauer commented Dec 6, 2023

🐛 Bug report

When using useSearchParams from Nextjs and Remix with Select component causes multiple reenders.

Radix and Ariakit are working fine: chakra-ui/ark#1817 (comment)

💥 Steps to reproduce

  1. Clone the repo https://github.com/juliomuhlbauer/use-search-param-ark
  2. Go to: https://github.com/juliomuhlbauer/use-search-param-ark/blob/main/src/app/search-param-zag/page.tsx
  3. Open the browser console
  4. Try to change the value and see the reenders

💻 Link to reproduction

In production Zag seems to work: https://use-search-param-ark.vercel.app/search-param-zag, but only if it does not have other heavy components that slow the render.
Ark UI for example does reenders on production: Nextjs + ARK example and Remix + ARK example

🧐 Expected behavior

Render only 1 time when searchParams change

🧭 Possible Solution

I think there is something with how Zag works.
And changing searchParams change the Nextjs dom structure which Zag depends on? Don't know.

I dont't think there is a problem with Nextjs or Remix as Ariakit and Radix are working fine. I think it is related on how Zag interacts with DOM and the framework integration.

We should have examples on how to integrate like the useSearchParam hook with the Ark/Zag components and how to mitigate this errors.

🌍 System information

Software Version(s)
Zag Version 0.31.1
Browser Chrome 119
Operating System Windows

📝 Additional information

ARK issue: chakra-ui/ark#1817 (comment)

GitHub Repo: https://github.com/juliomuhlbauer/use-search-param-ark

I am open for contribution. This bug is really affecting my application. I am trying to come up with different solutions but none works great. I am thinking to use Ariakit for now. I want to go big with Ark on quintohectare.com. I appreciate all the work the Chakra team is doing and I am open to help with this.

2023-12-06.18-58-55.mp4
@cschroeter
Copy link
Member

@juliomuhlbauer

I spent some time digging into this, and Next.js states how to update search params in their App framework. The following code snippets should work just fine:

If this solves your issue, feel free to Buy me a coffee for solving your issue ;)

"use client";
import { Select } from "@ark-ui/react";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useCallback, useEffect } from "react";

const items = [
  {
    label: "Germany",
    value: "de",
  },
  {
    label: "United Kingdom",
    value: "uk",
  },
  {
    label: "France",
    value: "fr",
  },
  {
    label: "Nigeria",
    value: "ng",
  },
  {
    label: "Spain",
    value: "es",
  },
];

export const MySelect = () => {
  const searchParams = useSearchParams();
  const router = useRouter();
  const pathname = usePathname();

  const value = searchParams.get("country");

  const createQueryString = useCallback(
    (name: string, value: string) => {
      const params = new URLSearchParams(searchParams);
      params.set(name, value);

      return params.toString();
    },
    [searchParams]
  );

  useEffect(() => {
    console.log("searchParams", searchParams);
  }, [searchParams]);

  return (
    <div>
      <Select.Root
        items={items}
        value={value ? [value] : []}
        onValueChange={(x) => console.log(x)}
      >
        <Select.Label>Framework</Select.Label>
        <Select.Control>
          <Select.ValueText placeholder="Select a Country" />
        </Select.Control>
        <Select.Positioner>
          <Select.Content>
            <Select.ItemGroup id="framework">
              <Select.ItemGroupLabel htmlFor="framework">
                Frameworks
              </Select.ItemGroupLabel>
              {items.map((item) => (
                <Select.Item key={item.value} item={item}>
                  <Select.ItemText>{item.label}</Select.ItemText>
                  <Select.ItemIndicator></Select.ItemIndicator>
                </Select.Item>
              ))}
            </Select.ItemGroup>
          </Select.Content>
        </Select.Positioner>
      </Select.Root>
      <p>Search: {value}</p>
      <button
        onClick={() => {
          router.push(pathname + "?" + createQueryString("country", "uk"));
        }}
      >
        Set Country to UK
      </button>
    </div>
  );
};

@juliomuhlbauer
Copy link
Contributor Author

juliomuhlbauer commented Dec 7, 2023

@cschroeter

The example doesn't prevent reenders.
And adding more items to the list blocks the render.

I made two examples showcasing that the length of the items blocks the render in Ark and Ariakit don't.

Ark demo: https://use-search-param-ark.vercel.app/search-param-ark-example-longlist

Ariakit with the same items works fine: https://use-search-param-ark.vercel.app/search-param-ariakit

Zag works only on production sometimes: https://use-search-param-ark.vercel.app/search-param-zag, but not in dev.

2023-12-07.15-05-27.mp4

@juliomuhlbauer
Copy link
Contributor Author

Seems to me an error with the context value given to Zag

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants