diff --git a/__tests__/atomWithHash_spec.tsx b/__tests__/atomWithHash_spec.tsx
index 443b5b4..1491fa9 100644
--- a/__tests__/atomWithHash_spec.tsx
+++ b/__tests__/atomWithHash_spec.tsx
@@ -1,4 +1,4 @@
-import React, { StrictMode, useMemo } from 'react';
+import React, { StrictMode, useEffect, useMemo, useState } from 'react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { useAtom } from 'jotai/react';
@@ -186,6 +186,37 @@ describe('atomWithHash', () => {
await user.type(screen.getByLabelText('b'), '1');
await waitFor(() => expect(paramBMockFn).toBeCalledTimes(4));
});
+
+ it('sets initial value from hash', async () => {
+ window.location.hash = '#count=2';
+ const countAtom = atomWithHash('count', 0);
+
+ const Counter = () => {
+ const [count] = useAtom(countAtom);
+ const [countWasZero, setCountWasZero] = useState(false);
+
+ useEffect(() => {
+ if (count === 0) {
+ setCountWasZero(true);
+ }
+ }, [count]);
+ return (
+ <>
+
count: {count}
+ count was zero: {countWasZero.toString()}
+ >
+ );
+ };
+
+ const { findByText } = render(
+
+
+ ,
+ );
+
+ await findByText('count: 2');
+ await findByText('count was zero: false');
+ });
});
describe('atomWithHash without window', () => {
diff --git a/src/atomWithHash.ts b/src/atomWithHash.ts
index 120b6e9..76b5d58 100644
--- a/src/atomWithHash.ts
+++ b/src/atomWithHash.ts
@@ -26,6 +26,7 @@ export function atomWithHash(
},
): WritableAtom], void> {
const serialize = options?.serialize || JSON.stringify;
+
const deserialize = options?.deserialize || safeJSONParse(initialValue);
const subscribe =
options?.subscribe ||
@@ -51,15 +52,20 @@ export function atomWithHash(
if (typeof setHashOption === 'function') {
setHash = setHashOption;
}
- const strAtom = atom(null);
+ const isLocationAvailable =
+ typeof window !== 'undefined' && !!window.location;
+
+ const strAtom = atom(
+ isLocationAvailable
+ ? new URLSearchParams(window.location.hash.slice(1)).get(key)
+ : null,
+ );
strAtom.onMount = (setAtom) => {
- if (typeof window === 'undefined' || !window.location) {
+ if (!isLocationAvailable) {
return undefined;
}
const callback = () => {
- const searchParams = new URLSearchParams(window.location.hash.slice(1));
- const str = searchParams.get(key);
- setAtom(str);
+ setAtom(new URLSearchParams(window.location.hash.slice(1)).get(key));
};
const unsubscribe = subscribe(callback);
callback();