Skip to content

Commit

Permalink
Merge pull request #111 from charlie-tango/feat/revalidate-cookies
Browse files Browse the repository at this point in the history
  • Loading branch information
thebuilder authored Dec 4, 2024
2 parents dcc7ed0 + f339a7c commit 6c5bbca
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 5 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ import { useCookie } from "@charlietango/hooks/use-cookie";
const [value, setValue] = useCookie("mode");
```

If the cookies is changed outside the `useCookie` hook, you can call the `revalidateCookies`, to get React to reevaluate the cookie values.

```ts
import { revalidateCookies } from "@charlietango/hooks/use-cookie";

revalidateCookies();
```

### `useDebouncedValue`

Debounce a value. The value will only be updated after the delay has passed without the value changing.
Expand Down
30 changes: 25 additions & 5 deletions src/__tests__/useCookie.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { act, renderHook } from "@testing-library/react";
import { useCookie } from "../hooks/useCookie";
import { revalidateCookies, useCookie } from "../hooks/useCookie";

function setValue(
value: string | ((prevValue?: string) => string | undefined) | undefined,
Expand All @@ -14,8 +14,15 @@ function getValue(hook: { current: ReturnType<typeof useCookie> }) {
return hook.current[0];
}

afterEach(() => {
// Clear all cookies after each test
document.cookie.split(";").forEach((c) => {
document.cookie = `${c.trim().split("=")[0]}=;expires=Thu, 01 Jan 1970 00:00:00 UTC;`;
});
});

test("should manage cookies", () => {
const { result: hook } = renderHook(() => useCookie("test"));
const { result: hook } = renderHook(() => useCookie("manage-test"));

setValue("custom value", hook);

Expand All @@ -30,7 +37,7 @@ test("should manage cookies", () => {

test("should manage cookies with default value", () => {
const { result: hook } = renderHook(() =>
useCookie("test", { defaultValue: "default value" }),
useCookie("default-value", { defaultValue: "default value" }),
);

expect(getValue(hook)).toBe("default value");
Expand All @@ -43,11 +50,24 @@ test("should manage cookies with default value", () => {
});

test("should sync values across hooks", () => {
const { result: hook } = renderHook(() => useCookie("test"));
const { result: hook2 } = renderHook(() => useCookie("test"));
const { result: hook } = renderHook(() => useCookie("sync"));
const { result: hook2 } = renderHook(() => useCookie("sync"));

setValue("new value", hook);

expect(getValue(hook)).toBe("new value");
expect(getValue(hook2)).toBe("new value");
});

test("should be able to revalidate cookies externally", () => {
const { result: hook } = renderHook(() => useCookie("external"));
document.cookie = "external=new value";
expect(hook.current[0]).toBe(undefined);

act(() => {
// Revalidate the cookies, trigger the external sync
revalidateCookies();
});

expect(hook.current[0]).toBe("new value");
});
7 changes: 7 additions & 0 deletions src/hooks/useCookie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ type Options = {
cookieOptions?: CookieOptions;
};

/**
* Revalidate the cookies. Useful to update the cookies when they are changed outside the hook, e.g. by a server response.
*/
export function revalidateCookies() {
trigger(SUBSCRIPTION_KEY);
}

/**
* Get or set a cookie, and update the value when it changes
* @param key {string} The name of the cookie.
Expand Down

0 comments on commit 6c5bbca

Please sign in to comment.