From f5fea681bff832ba60577576609a81e974ccdf5b Mon Sep 17 00:00:00 2001 From: Cody Partington <94301860+CodyCodes95@users.noreply.github.com> Date: Tue, 28 Nov 2023 11:48:36 +1100 Subject: [PATCH 1/4] Update connect-to-state-with-url-hash.md Resolved a few errors and type errors in the persist and create state with URL example: 1. createJsonStorage not being called in storageOptions resulting in a type error. 2. Correct hook not being exported 3. Moved the creation of initial state inline to get the correct types passed from create/persist. 4. Used state type as generic for persist. --- docs/guides/connect-to-state-with-url-hash.md | 78 +++++++++++-------- 1 file changed, 44 insertions(+), 34 deletions(-) diff --git a/docs/guides/connect-to-state-with-url-hash.md b/docs/guides/connect-to-state-with-url-hash.md index 56de432e6d..418f06d87e 100644 --- a/docs/guides/connect-to-state-with-url-hash.md +++ b/docs/guides/connect-to-state-with-url-hash.md @@ -58,60 +58,70 @@ If you want the URL params to always populate, the conditional check on `getUrlS The implementation below will update the URL in place, without refresh, as the relevant states change. ```ts -import { create } from 'zustand' -import { persist, StateStorage, createJSONStorage } from 'zustand/middleware' +import { create } from "zustand"; +import { persist, StateStorage, createJSONStorage } from "zustand/middleware"; const getUrlSearch = () => { - return window.location.search.slice(1) -} + return window.location.search.slice(1); +}; const persistentStorage: StateStorage = { getItem: (key): string => { // Check URL first if (getUrlSearch()) { - const searchParams = new URLSearchParams(getUrlSearch()) - const storedValue = searchParams.get(key) - return JSON.parse(storedValue) + const searchParams = new URLSearchParams(getUrlSearch()); + const storedValue = searchParams.get(key); + return JSON.parse(storedValue as string); } else { // Otherwise, we should load from localstorage or alternative storage - return JSON.parse(localStorage.getItem(key)) + return JSON.parse(localStorage.getItem(key) as string); } }, setItem: (key, newValue): void => { // Check if query params exist at all, can remove check if always want to set URL if (getUrlSearch()) { - const searchParams = new URLSearchParams(getUrlSearch()) - searchParams.set(key, JSON.stringify(newValue)) - window.history.replaceState(null, null, `?${searchParams.toString()}`) + const searchParams = new URLSearchParams(getUrlSearch()); + searchParams.set(key, JSON.stringify(newValue)); + window.history.replaceState(null, "", `?${searchParams.toString()}`); } - localStorage.setItem(key, JSON.stringify(newValue)) + localStorage.setItem(key, JSON.stringify(newValue)); }, removeItem: (key): void => { - const searchParams = new URLSearchParams(getUrlSearch()) - searchParams.delete(key) - window.location.search = searchParams.toString() + const searchParams = new URLSearchParams(getUrlSearch()); + searchParams.delete(key); + window.location.search = searchParams.toString(); }, -} - -let localAndUrlStore = (set) => ({ - typesOfFish: [], - addTypeOfFish: (fishType) => - set((state) => ({ typesOfFish: [...state.typesOfFish, fishType] })), - - numberOfBears: 0, - setNumberOfBears: (newNumber) => - set((state) => ({ numberOfBears: newNumber })), -}) - -let storageOptions = { - name: 'fishAndBearsStore', - storage: persistentStorage, -} - -const useLocalAndUrlStore = create(persist(localAndUrlStore, storageOptions)) +}; + +type LocalAndUrlStore = { + typesOfFish: string[]; + addTypeOfFish: (fishType: string) => void; + numberOfBears: number; + setNumberOfBears: (newNumber: number) => void; +}; + +const storageOptions = { + name: "fishAndBearsStore", + storage: createJSONStorage(() => persistentStorage), +}; + +const useLocalAndUrlStore = create( + persist( + (set) => ({ + typesOfFish: [], + addTypeOfFish: (fishType) => + set((state) => ({ typesOfFish: [...state.typesOfFish, fishType] })), + + numberOfBears: 0, + setNumberOfBears: (newNumber) => + set(() => ({ numberOfBears: newNumber })), + }), + storageOptions, + ), +); -export default localAndUrlStore +export default useLocalAndUrlStore; ``` When generating the URL from a component, you can call buildShareableUrl: From 43368748b8cddf56e18cbcbfe17af3a21c6a55b5 Mon Sep 17 00:00:00 2001 From: Cody Partington Date: Tue, 28 Nov 2023 11:56:06 +1100 Subject: [PATCH 2/4] yarn prettier run --- docs/guides/connect-to-state-with-url-hash.md | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/docs/guides/connect-to-state-with-url-hash.md b/docs/guides/connect-to-state-with-url-hash.md index 418f06d87e..407b089738 100644 --- a/docs/guides/connect-to-state-with-url-hash.md +++ b/docs/guides/connect-to-state-with-url-hash.md @@ -58,53 +58,53 @@ If you want the URL params to always populate, the conditional check on `getUrlS The implementation below will update the URL in place, without refresh, as the relevant states change. ```ts -import { create } from "zustand"; -import { persist, StateStorage, createJSONStorage } from "zustand/middleware"; +import { create } from 'zustand' +import { persist, StateStorage, createJSONStorage } from 'zustand/middleware' const getUrlSearch = () => { - return window.location.search.slice(1); -}; + return window.location.search.slice(1) +} const persistentStorage: StateStorage = { getItem: (key): string => { // Check URL first if (getUrlSearch()) { - const searchParams = new URLSearchParams(getUrlSearch()); - const storedValue = searchParams.get(key); - return JSON.parse(storedValue as string); + const searchParams = new URLSearchParams(getUrlSearch()) + const storedValue = searchParams.get(key) + return JSON.parse(storedValue as string) } else { // Otherwise, we should load from localstorage or alternative storage - return JSON.parse(localStorage.getItem(key) as string); + return JSON.parse(localStorage.getItem(key) as string) } }, setItem: (key, newValue): void => { // Check if query params exist at all, can remove check if always want to set URL if (getUrlSearch()) { - const searchParams = new URLSearchParams(getUrlSearch()); - searchParams.set(key, JSON.stringify(newValue)); - window.history.replaceState(null, "", `?${searchParams.toString()}`); + const searchParams = new URLSearchParams(getUrlSearch()) + searchParams.set(key, JSON.stringify(newValue)) + window.history.replaceState(null, '', `?${searchParams.toString()}`) } - localStorage.setItem(key, JSON.stringify(newValue)); + localStorage.setItem(key, JSON.stringify(newValue)) }, removeItem: (key): void => { - const searchParams = new URLSearchParams(getUrlSearch()); - searchParams.delete(key); - window.location.search = searchParams.toString(); + const searchParams = new URLSearchParams(getUrlSearch()) + searchParams.delete(key) + window.location.search = searchParams.toString() }, -}; +} type LocalAndUrlStore = { - typesOfFish: string[]; - addTypeOfFish: (fishType: string) => void; - numberOfBears: number; - setNumberOfBears: (newNumber: number) => void; -}; + typesOfFish: string[] + addTypeOfFish: (fishType: string) => void + numberOfBears: number + setNumberOfBears: (newNumber: number) => void +} const storageOptions = { - name: "fishAndBearsStore", + name: 'fishAndBearsStore', storage: createJSONStorage(() => persistentStorage), -}; +} const useLocalAndUrlStore = create( persist( @@ -119,9 +119,9 @@ const useLocalAndUrlStore = create( }), storageOptions, ), -); +) -export default useLocalAndUrlStore; +export default useLocalAndUrlStore ``` When generating the URL from a component, you can call buildShareableUrl: From 599de84fb8eacaef06433a546096d9aa08126cb0 Mon Sep 17 00:00:00 2001 From: Cody Partington <94301860+CodyCodes95@users.noreply.github.com> Date: Tue, 28 Nov 2023 17:59:18 +1100 Subject: [PATCH 3/4] Update docs/guides/connect-to-state-with-url-hash.md Better name for state in setter Co-authored-by: Danilo Britto --- docs/guides/connect-to-state-with-url-hash.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guides/connect-to-state-with-url-hash.md b/docs/guides/connect-to-state-with-url-hash.md index 407b089738..d4998b94bf 100644 --- a/docs/guides/connect-to-state-with-url-hash.md +++ b/docs/guides/connect-to-state-with-url-hash.md @@ -114,8 +114,8 @@ const useLocalAndUrlStore = create( set((state) => ({ typesOfFish: [...state.typesOfFish, fishType] })), numberOfBears: 0, - setNumberOfBears: (newNumber) => - set(() => ({ numberOfBears: newNumber })), + setNumberOfBears: (numberOfBears) => + set(() => ({ numberOfBears })), }), storageOptions, ), From caee831913841e77c86c60050abffdf6b230e8d4 Mon Sep 17 00:00:00 2001 From: Cody Partington Date: Tue, 28 Nov 2023 18:12:19 +1100 Subject: [PATCH 4/4] prettier run --- docs/guides/connect-to-state-with-url-hash.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/guides/connect-to-state-with-url-hash.md b/docs/guides/connect-to-state-with-url-hash.md index d4998b94bf..d006e6ec18 100644 --- a/docs/guides/connect-to-state-with-url-hash.md +++ b/docs/guides/connect-to-state-with-url-hash.md @@ -114,8 +114,7 @@ const useLocalAndUrlStore = create( set((state) => ({ typesOfFish: [...state.typesOfFish, fishType] })), numberOfBears: 0, - setNumberOfBears: (numberOfBears) => - set(() => ({ numberOfBears })), + setNumberOfBears: (numberOfBears) => set(() => ({ numberOfBears })), }), storageOptions, ),