Сохранение и подключение состояния с помощью параметров URL (пример: параметры запроса URL)¶
Бывают случаи, когда необходимо условно связать состояние с URL. В этом примере показано использование параметров запроса URL при сохранении синхронизации с другой реализацией персистентности, например localstorage.
Если вы хотите, чтобы параметры URL всегда заполнялись, условную проверку на getUrlSearch() можно убрать.
Реализация, представленная ниже, будет обновлять URL на месте, без обновления, по мере изменения соответствующих состояний.
import{create}from'zustand';import{persist,StateStorage,createJSONStorage,}from'zustand/middleware';constgetUrlSearch=()=>{returnwindow.location.search.slice(1);};constpersistentStorage:StateStorage={getItem:(key):string=>{// Check URL firstif(getUrlSearch()){constsearchParams=newURLSearchParams(getUrlSearch());conststoredValue=searchParams.get(key);returnJSON.parse(storedValueasstring);}else{// Otherwise, we should load from localstorage or alternative storagereturnJSON.parse(localStorage.getItem(key)asstring);}},setItem:(key,newValue):void=>{// Check if query params exist at all, can remove check if always want to set URLif(getUrlSearch()){constsearchParams=newURLSearchParams(getUrlSearch());searchParams.set(key,JSON.stringify(newValue));window.history.replaceState(null,'',`?${searchParams.toString()}`);}localStorage.setItem(key,JSON.stringify(newValue));},removeItem:(key):void=>{constsearchParams=newURLSearchParams(getUrlSearch());searchParams.delete(key);window.location.search=searchParams.toString();},};typeLocalAndUrlStore={typesOfFish:string[];addTypeOfFish:(fishType:string)=>void;numberOfBears:number;setNumberOfBears:(newNumber:number)=>void;};conststorageOptions={name:'fishAndBearsStore',storage:createJSONStorage<LocalAndUrlStore>(()=>persistentStorage),};constuseLocalAndUrlStore=create(persist<LocalAndUrlStore>((set)=>({typesOfFish:[],addTypeOfFish:(fishType)=>set((state)=>({typesOfFish:[...state.typesOfFish,fishType,],})),numberOfBears:0,setNumberOfBears:(numberOfBears)=>set(()=>({numberOfBears})),}),storageOptions));exportdefaultuseLocalAndUrlStore;
При генерации URL из компонента вы можете вызвать buildShareableUrl:
1 2 3 4 5 6 7 8 910111213141516171819202122232425
constbuildURLSuffix=(params,version=0)=>{constsearchParams=newURLSearchParams();constzustandStoreParams={state:{typesOfFish:params.typesOfFish,numberOfBears:params.numberOfBears,},version:version,// version is here because that is included with how Zustand sets the state};// The URL param key should match the name of the store, as specified as in storageOptions abovesearchParams.set('fishAndBearsStore',JSON.stringify(zustandStoreParams));returnsearchParams.toString();};exportconstbuildShareableUrl=(params,version)=>{return`${window.location.origin}?${buildURLSuffix(params,version)}`;};
Сгенерированный URL будет выглядеть так (здесь без кодировки, для удобства чтения):