Black Sheep Code
rss_feed

How to create a responsive React hook to listen for changes to cookies

Published:

I recently encountered a situation where I have some React code that needs to listen for changes to a cookie, but this cookie logic isn't controlled React.

Some searches reveal tutorial posts like this one that implement a useCookie hook.

This works kind of nicely, we get a nice useState style hook, that also stores into cookies as a side effect, it's helpful for retainining state between sessions.

However, this solution is not responsive to cookie changes that may occur outside of the React context. In fact, two components that were examining the same cookie would not have their updates be observed by the other.

☝️ Interactive demo

Name: John Doe

Age: 30

Server cookie: default-value-for-server-cookie

Click the 'Update User' button and observe the value changes.

Open your browser dev tools.

Observe that when you click 'Update User' a `user-1` cookie is set in the Applications tab.

Observe that when you click 'Server Fetch' an API call is made, and that Response contains a cookie. However our application will not respond to this cookie.

The scenarios where cookies may be set outside of a React context are:

We can use the CookieChangeEvent to make a useCookie hook truely responsive.

warning

The CookieStore is not currently supported by Firefox or Safari.

I couldn't a CookieStore polyfill. There is the cookie-store project - but this has not implemented the CookieStore Monitoring Cookies feature. See this issue: markcellus/cookie-store#46 Monitoring Cookies feature

My solution implements the polling solution described in this Stack Overflow answer

Note that on a page refresh the values initially show as 'John Doe' and then cookie value pops in. This is because this blog is has server rendering, and this these solutions access the client cookies. Cookies are available to the server - a solution that avoids this flash is available in this post here.

The a polyfilled implementation of a responsive useCookie looks like this:

☝️ Interactive demo

Name: John Doe

Age: 30

Server cookie: default-value-for-server-cookie

Using Chrome observe that our component now responds to cookies set by the api response

Observe that this also works for Firefox. It appears sluggish - this is due the 1000ms poll rate. You can decrease the poll rate for snappier application, this will come at the cost of extra computation for the user.



Questions? Comments? Criticisms? Get in the comments! 👇

Spotted an error? Edit this page with Github