From 19a3c1a6cabe23bf7f971708e68feb09f605ce53 Mon Sep 17 00:00:00 2001 From: Filip Lindahl Date: Tue, 27 Feb 2024 11:07:36 +0100 Subject: [PATCH 1/2] feat(atomWithHash): initial value from hash (#31) * setup test for initial value * use value in hash if present * adjust after comments on PR * refactor more, cleaner more contained solution --- __tests__/atomWithHash_spec.tsx | 33 ++++++++++++++++++++++++++++++++- src/atomWithHash.ts | 16 +++++++++++----- 2 files changed, 43 insertions(+), 6 deletions(-) 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(); From 289e84b859c83a588e21e817b165720fe4319e0d Mon Sep 17 00:00:00 2001 From: Filip Lindahl Date: Tue, 27 Feb 2024 13:58:59 +0100 Subject: [PATCH 2/2] v0.5.4 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6df4633..0563471 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +## [0.5.4] - 2024-02-27 +### Changed +- feat(atomWithHash): initial value from hash #31 + ## [0.5.3] - 2024-02-18 ### Changed - feat(atomWithLocation): override replace for specific navigations #28 diff --git a/package.json b/package.json index 92312b1..06e1838 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "jotai-location", "description": "👻🔗", - "version": "0.5.3", + "version": "0.5.4", "author": "Daishi Kato", "repository": { "type": "git",