diff --git a/src/useLocalStorage.test.tsx b/src/useLocalStorage.test.tsx index 4b0a058d..8cb66b77 100644 --- a/src/useLocalStorage.test.tsx +++ b/src/useLocalStorage.test.tsx @@ -7,7 +7,8 @@ Please see LICENSE in the repository root for full details. import { test } from "vitest"; import { render, screen } from "@testing-library/react"; -import { type FC, useEffect } from "react"; +import { type FC, useEffect, useState } from "react"; +import userEvent from "@testing-library/user-event"; import { setLocalStorageItem, useLocalStorage } from "./useLocalStorage"; @@ -21,3 +22,27 @@ test("useLocalStorage reacts to changes made by an effect mounted on the same re render(); screen.getByText("Hello!"); }); + +test("useLocalStorage reacts to key changes", async () => { + localStorage.clear(); + localStorage.setItem("value-1", "1"); + localStorage.setItem("value-2", "2"); + + const Test: FC = () => { + const [key, setKey] = useState("value-1"); + const [value] = useLocalStorage(key); + if (key !== `value-${value}`) throw new Error("Value is out of sync"); + return ( + <> + +
Value is: {value}
+ + ); + }; + const user = userEvent.setup(); + render(); + + screen.getByText("Value is: 1"); + await user.click(screen.getByRole("button", { name: "Switch keys" })); + screen.getByText("Value is: 2"); +}); diff --git a/src/useLocalStorage.ts b/src/useLocalStorage.ts index 517c7c62..e96c9c87 100644 --- a/src/useLocalStorage.ts +++ b/src/useLocalStorage.ts @@ -6,9 +6,10 @@ Please see LICENSE in the repository root for full details. */ import EventEmitter from "events"; -import { useCallback, useEffect, useState } from "react"; +import { useCallback, useEffect } from "react"; import { useLatest } from "./useLatest"; +import { useReactiveState } from "./useReactiveState"; type LocalStorageItem = ReturnType; @@ -19,8 +20,9 @@ export const localStorageBus = new EventEmitter(); export const useLocalStorage = ( key: string, ): [LocalStorageItem, (value: string) => void] => { - const [value, setValue] = useState(() => - localStorage.getItem(key), + const [value, setValue] = useReactiveState( + () => localStorage.getItem(key), + [key], ); const latestValue = useLatest(value);