UNPKG

state-in-url

Version:

Store state in URL as in object, types and structure are preserved, with TS validation. Same API as React.useState, wthout any hasssle or boilerplate. Next.js@14-15, react-router@6-7, and remix@2.

2 lines (1 loc) 1.27 kB
import r from"react";import{useRouter as y}from"next/navigation";import{parseSPObj as p}from"../../parseSPObj.mjs";import{useUrlStateBase as C}from"../../useUrlStateBase/useUrlStateBase.mjs";import{routerHistory as m,filterUnknownParams as f,getParams as v,subscribeToUrl as H,isSSR as M,filterUnknownParamsClient as j,getSearch as S}from"../../utils.mjs";function w(s,t){const l=r.useMemo(()=>t?.useHistory===void 0?true:!!t?.useHistory,[]);const o=y();const U=r.useMemo(()=>({push:(...e)=>{if(l){m.push(...e)}else{o.push(...e)}},replace:(...e)=>{if(l){m.replace(...e)}else{o.replace(...e)}}}),[o]);const{state:b,updateState:c,updateUrl:u,reset:n,getState:d,pendingUrlUpdate:h}=C(s,U,({parse:e})=>{return M?p(f(s,t?.searchParams),s):e(j(s,t?.searchParams||S()))});const a=r.useCallback(()=>{if(h())return;c(f(s,p(Object.fromEntries(v(S()).entries()),s)))},[]);r.useEffect(()=>{a();return H(a)},[a]);const i=r.useMemo(()=>{const e={...E};if(t?.scroll!==void 0)e.scroll=t.scroll;if(t?.replace!==void 0)e.replace=t.replace;return e},[t?.scroll,t?.replace]);const P=r.useCallback((e,k)=>u(e,{...i,...k}),[u]);const g=r.useCallback(e=>{n({...i,...e})},[n]);return{setState:c,setUrl:P,urlState:b,reset:g,getState:d}}const E={replace:true,scroll:false};export{w as useUrlState};