8000 feat: Make hooks trigger rerender. by greg2012201 · Pull Request #99 · andreizanik/cookies-next · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat: Make hooks trigger rerender. #99

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

Open
wants to merge 17 commits into
base: master
Choose a base branch
from

Conversation

greg2012201
Copy link
Contributor
@greg2012201 greg2012201 commented Apr 4, 2025

Hello! 👋🏻 @yasinitskyi @andreizanik

Here is the fix for the issue: #97. I've added a little workaround with using state updates to ensure component re-render when cookies change.

As always, please test the PR on some Next.js project before merge (I might have missed something).

Thanks in advance for the code review.

@yasinitskyi
Copy link

@greg2012201 @andreizanik wow, thx for taking actions, looking forward to this being in production!

@andreizanik
Copy link
Owner

Hello!
@greg2012201 thanks for your PR, @yasinitskyi thanks for your idea

Cookie storage is not state manager like redux or mobx. And update cookie value shouldn't trigger a rerender of the component. Standard cookie libraries are not reactive
Also, cookies can be set with any request to the backend (not just on the client side).

I think, if we merge this PR we will break the expected behavior of working with cookies

But I understand that it can be useful for some developers.

May be it'll be better to implement new hooks (something like getCookiesReactive, setCookiesReactive) and the old exported functions and hooks to remain unchanged?
Any idea?

@yasinitskyi
Copy link
yasinitskyi commented Apr 7, 2025

@andreizanik @greg2012201
Thank you for your response!

I understand what you are saying, however, since package has different set of functions that are having read on cookie store, which some of them are just normal functions (such as getCookie, setCookie etc) and some of them are hooks (useGetCookies, useSetCookie etc.), I personally would expect second set (namely hooks) be reactive since hooks in react basically functions that remember things or do, from both my own experience and the documentation, these hooks don’t appear to behave any differently than the regular functions, aside from helping avoid hydration mismatches., other than that they are acting the same. What I am trying to express here is if function is named useXYZ I expect it to either manage state or respond to some sort of reactive change (e.g. useQuery, useLocation, useTheme, etc), If it’s just a getter in disguise, it should probably not be a hook but a normal function which we already have in the package.

I respect your concern about such change that may cause breaking changes in the code, so I think it either can be a separate hook in the package or just application of fix to all hooks in the library and making it a part of some major release with announcement of migration guide and major change description would be the way to go (for me personally), since I still expect those hooks work the way I just described above (due to developer experience mismatch).

Looking forward to hearing your opinion about this concern!

Thank you for finding time to review my github issue and respond to it, very appreciate that!

@greg2012201
Copy link
Contributor Author

I think we can add reactive hooks for setter functions only.
My implementation of reactivity does not hold the actual state of the cookie store — it uses a small hack to simply trigger a re-render.
Hooks that return getters just read the state of the cookie storage after a re-render (in this case, nothing has changed).

Regarding @yasinitskyi’s point about hooks:
In my view, hooks are not always meant to trigger re-renders or maintain state. For example, useRef does not cause a re-render and does not maintain a state of the component.
Previously, I added hooks to the library as a solution for hydration issues in client components that are initially rendered on the server.

I understand both of your perspectives, and I’m proposing the following changes:

  • Add additional hooks: useSetCookieReactive and useDeleteCookieReactive

  • Add information about them to the documentation

What do you think?

@yasinitskyi
Copy link

@greg2012201 thank you for your sharing on this matter, and thank you for your proposal. I think either way how you want to go about it, either tweak previous hooks or add new set of hooks to unlock/expand needed behavior, will work. As long as we can get the functionality, I think we are good.

@andreizanik

@yasinitskyi
Copy link

@greg2012201 Small detail, it is important I guess not only get re-rendering on cookie set but also on cookie get, if cookies are set in one component but are read in another... Reactivity from set function would be helpful in terms of the same scope, but it is not always the case, you would want reactivity on read as well, like from my example in #97

@andreizanik
Copy link
Owner
andreizanik commented Apr 14, 2025

if cookies are set in one component but are read in another...

@yasinitskyi I agree with you. If we decide to add reactivity, we must add it to all hooks

And setting/delete/update cookies in one component should force re-render to other components that use hooks useGetCookie('name_of_the_changed_cookie'), useHasCookie('name_of_the_changed_cookie'), useGetCookies()

or useGetCookieReactive('name_of_the_changed_cookie'), useHasCookieReactive('name_of_the_changed_cookie'), useGetCookiesReactive()

In my opinion, without this, the update doesn't make sense

@greg2012201 what do you think?

@greg2012201
Copy link
Contributor Author

I generally agree.

If we decide to move forward with this, we have at least two implementation options:

  • Use some form of pub-sub (maybe an event emitter could work)
  • Handle it via React context, which we’d need to return so users can include it in their component tree

Which approach do we want to go with?

P.S. If we decide to proceed, I’ll need approximately a month to ship these changes, as I’m currently a bit busy.

@greg2012201
Copy link
Contributor Author

@andreizanik, which approach do we want to pursue?

@yasinitskyi
Copy link

@greg2012201 I might not be an expert here, but I feel context may not be a good idea since it will lead to whole tree to re-render which is not ideal, event sound more legit perhaps...

@andreizanik
Copy link
Owner

In my opinion context will be better. Because it is providing by React and it will be more familiar for developers.

We often use different providers if we want to get rerendering after data mutation (For instance TanStack Query and different tools for state managment). I think it's our case.

This is my opinion and I am open to discussion

@greg2012201
Copy link
Contributor Author
greg2012201 commented Apr 25, 2025

It’s fine by me. Using context for that type of stuff is a well-established pattern in the React ecosystem, and it should work well.

@greg2012201
Copy link
Contributor Author
greg2012201 commented May 10, 2025

@yasinitskyi @andreizanik

I have completed the implementation of reactive hooks. Here’s what’s included:

  • The reactive 8000 hooks offer the same API as the existing hooks, with only the names differing.
  • The hooks require adding the CookiesNextProvider.
  • They can detect cookies set on the server through polling on document.cookie (disabled by default). Users can configure this option via the CookiesNextProvider props.
  • To prevent circular dependencies and keep the code clean, I split some parts of the code into separate modules.
  • I’ve added unit tests for the new hooks and the provider.
  • I added new dev dependencies required for testing and removed a redundant one, replacing it with a more suitable alternative.
  • I updated the documentation.

I also discovered a potential issue with the getCookies function. The cookie output is not decoded or parsed, so instead of returning a valid cookies object, it returns raw string data.

For now, the same issue persists in the functions returned from the reactive hooks (getCookies, getCookie). If needed, After merging the current PR I can submit an another to address this. Let me know if you would like me to proceed. The issue: #101


I believe my changes will make cookies-next more appealing to Next.js developers.

As always, I performed manual testing, but I would appreciate it if you could also review and test the code to ensure quality.

Looking forward to your feedback!

@andreizanik
Copy link
Owner

@greg2012201
Hi,
After short check I came up with an idea.
Pooling is a good idea, but how about manual trigger for update cookies?
I think developers often won't need constantly synchronize context with document.cookies. Synchronization will only be needed in specific situations. For example after authorization or after every request to API
In this case it would be better to have a function(hook) that can be called at any time.

That is, we will be able to implement such a behavior when we will synchronize the context only when it is necessary and without delays related to poolingOptions.intervalMs

What do you think?

@greg2012201
Copy link
Contributor Author
greg2012201 commented May 10, 2025

It might be a good idea. I could create a new hook called revalidateCookieState or something similar. I also think that polling should remain as it is since other tools use polling to track the document.cookie state.

Since I will be busy for the next 2-3 weeks, I suggest merging the current PR for now. I can then create a new one with this manual refresh feature when I’m available.

@andreizanik What do you think?

@andreizanik
Copy link
Owner

Got it.
So, I need a little time to review your PR, because it was just short check
Thanks!

@greg2012201 greg2012201 changed the title fix: Make hooks trigger rerender. feat: Make hooks trigger rerender. May 10, 2025
@greg2012201
Copy link
Contributor Author

Ok, I am looking forward to your review.

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
0