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

Regression: Component conditionally rendered on query parameter fails to update hook value from null to non-null #702

Closed
firatciftci opened this issue Oct 23, 2024 · 5 comments · Fixed by #703
Labels
bug Something isn't working released

Comments

@firatciftci
Copy link

Context

What's your version of nuqs?

"nuqs": "2.0.3"

What framework are you using?

  • ✅ Next.js (app router)

Which version of your framework are you using?

 next: 14.2.16
 eslint-config-next: 14.2.16
 react: 18.3.1
 react-dom: 18.3.1
 typescript: 5.6.3

Description

After upgrading to [email protected] (from [email protected]), a regression appeared where changing a query parameter from null to any value does not trigger an update to the value stored in useQueryState(s) if the component that calls the hook is rendered conditionally. The hook returns null on initial change of the query parameter from null to a value, and starts behaving as expected only after subsequent changes to the query parameter.

Reproduction

Custom query parameter hook:

"use client";

import { parseAsString, useQueryStates } from "nuqs";

export function useSelectedItem() {
  return useQueryStates(
    { itemId: parseAsString, subItemId: parseAsString },
    {
      urlKeys: {
        itemId: "item",
        subItemId: "subitem",
      },
      history: "push",
    },
  );
}

The main component:

"use client";

import { useSelectedItem } from "@/hooks/use-selected-item";
import ChildComponent from "@/components/child-component";

export default function MainComponent() {
  const [{ itemId }] = useSelectedItem();

  return (
    <div>
      ...
      {itemId !== null ?
        <ChildComponent />
      : null}
      ...
  );
}

The child component:

"use client";

import { useSelectedItem } from "@/hooks/use-selected-item";

export default function ChildComponent() {
  const [{ itemId }] = useSelectedItem();

  return (
    <div>Item ID: {itemId}</div>
  );
}

There exists a separate component with a list of cards in which pressing on a card changes the itemId value to a specific string:

"use client";

import { useSelectedItem } from "@/hooks/use-selected-item";

export default function Cards() {
  const [_, setSelectedItem] = useSelectedItem();

  ...
  return (
    ...
    <button onClick={() => setSelectedItem("value1")}>
      Value 1
    </button>
    <button onClick={() => setSelectedItem("value2")}>
      Value 2
    </button>
    ...
  );
}

When no value is selected, pressing on the first button changes the URL appropriately, but <ChildComponent /> does not register that itemId is set to "value1"; it continues to return null. However, while itemId is "value1", a subsequent click on the second button changes the URL appropriately once again, and now <ChildComponent /> is able to register the query value as "value2".

Removing the conditional render of <ChildComponent /> makes the issue go away. This bug does not appear in the version of nuqs prior to version 2.

@firatciftci firatciftci added the bug Something isn't working label Oct 23, 2024
@franky47
Copy link
Member

franky47 commented Oct 23, 2024

Ah I thought this could come back up when I was refactoring for v2, but the test that covered it before passed.

I believe the issue was that we need to take the value from the update queue into account when reading the initial search params for the internal state. There was an issue for this, let me dig around and I'll come back to you.

Edit: yes it was #359. So maybe the test isn't going far enough.

@franky47
Copy link
Member

Could you try this and let me know if it fixes your problem please?

pnpm add https://pkg.pr.new/nuqs@703

@firatciftci
Copy link
Author

Seems to be fixed! Thank you so much once again for your super swift response.

@franky47
Copy link
Member

Cool, I'll find a way to properly test this to prevent regressions and I'll publish a release tomorrow.

Copy link

🎉 This issue has been resolved in version 2.0.4 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working released
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants