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

add support for Query Params #39

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open

Conversation

jiangtaste
Copy link

@jiangtaste jiangtaste commented Nov 24, 2024

Motivation:
Recoil is no longer actively maintained, and I have recently transitioned to using Jotai. I needed a solution for URL persistence with query parameters similar to what recoil-sync provides, so I implemented this feature in Jotai.

Use cases:
I’ve included a simple example under the examples/05_search_params, which demonstrates how to use the new functionality:

const pageAtom = atomWithSearchParams("key", "defaultValue");

This will result in a URL like: ?key=defaultValue.

Implementation approach:
The implementation builds on Jotai's atomWithLocation from the jotai-location library, combined with Jotai’s basic read-write derived atoms to manage the state and sync it with URL query parameters.

@jiangtaste jiangtaste closed this Nov 24, 2024
Copy link

codesandbox-ci bot commented Nov 24, 2024

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

@jiangtaste jiangtaste reopened this Nov 24, 2024
@dai-shi
Copy link
Member

dai-shi commented Nov 25, 2024

Can you add a description about motivation, use cases, implementation approach, and so forth?

@jiangtaste

This comment was marked as duplicate.

@dai-shi
Copy link
Member

dai-shi commented Nov 27, 2024

Re: #39 (comment)

Thanks. Can you also put them in the first commend of this PR?

My little concern is that the implementation is on top of atomWithLocation. I'm not sure if it's good or not. That said, the API of atomWithQueryParams("key", "defaultValue"); is straightforward, and we can refactor the implementation later if necessary.

I think to avoid confusion with #20, we should probably rename atomWithQueryParams to atomWithSearchParams.

Copy link
Member

@dai-shi dai-shi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution! It looks good overall.

src/index.ts Outdated Show resolved Hide resolved
@jiangtaste
Copy link
Author

I’ve added them to the first comment of the PR.

Renaming atomWithQueryParams to atomWithSearchParams avoids confusion with #20 and keeps things clear. Thanks!

* @param defaultValue - The default value of the search parameter.
* @returns A writable atom that manages the search parameter.
*/
export const atomWithSearchParams = <T>(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, then limit only to support string, number and boolean.

Suggested change
export const atomWithSearchParams = <T>(
export const atomWithSearchParams = <T extends string | number | boolean>(

and simply the code please?


// Determine the type of the default value and parse accordingly.
if (typeof defaultValue === 'number') {
return Number(value) as T;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check NaN and return defaultValue instead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NaN checking is not enough for '' case.

> Number('')
0

}

if (typeof defaultValue === 'string') {
return value as T;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check typeof string and return defaultValue otherwise.

}

// If the default value is an object, try to parse it as JSON.
return JSON.parse(value) as T;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just throw here.

throw new Error('unsupported value type');

}

if (typeof defaultValue === 'boolean') {
return (value === 'true') as T;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return the default value if it's not true or false.

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

Successfully merging this pull request may close these issues.

3 participants