From 3af832b53c986d451c46fcf739b6ef1fbe2095bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=90=E8=97=A4=E6=98=AD=E6=96=87?= Date: Thu, 14 Sep 2023 22:02:42 +0900 Subject: [PATCH 1/4] add stores props in LocationStateProvider --- packages/location-state-core/src/provider.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/location-state-core/src/provider.tsx b/packages/location-state-core/src/provider.tsx index 9844e74b..7be6cb05 100644 --- a/packages/location-state-core/src/provider.tsx +++ b/packages/location-state-core/src/provider.tsx @@ -10,13 +10,14 @@ export function LocationStateProvider({ ...props }: { syncer?: Syncer; + stores?: Record; children: ReactNode; }) { const [syncer] = useState( () => props.syncer ?? new NavigationSyncer(window.navigation), ); const [contextValue] = useState(() => ({ - stores: { + stores: props.stores ?? { session: new StorageStore(globalThis.sessionStorage), url: new URLStore(syncer), }, From 1f76a84252a3d1765d1d405c23204ea67b8f6337 Mon Sep 17 00:00:00 2001 From: "akfm.sato" <01047245@CF0286.local> Date: Fri, 15 Sep 2023 10:18:07 +0900 Subject: [PATCH 2/4] support create stores function props on Provider --- packages/location-state-core/src/provider.tsx | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/packages/location-state-core/src/provider.tsx b/packages/location-state-core/src/provider.tsx index 7be6cb05..d94cb6d8 100644 --- a/packages/location-state-core/src/provider.tsx +++ b/packages/location-state-core/src/provider.tsx @@ -1,30 +1,38 @@ import { LocationStateContext } from "./context"; import { StorageStore, Store, URLStore } from "./stores"; import { NavigationSyncer } from "./syncers"; - import { Syncer } from "./types"; import { ReactNode, useEffect, useState } from "react"; +type Stores = Record; +type CreateStores = (syncer: Syncer) => Stores; + +const createDefaultStores: CreateStores = (syncer) => ({ + session: new StorageStore(globalThis.sessionStorage), + url: new URLStore(syncer), +}); + export function LocationStateProvider({ children, ...props }: { syncer?: Syncer; - stores?: Record; + stores?: Stores | CreateStores; children: ReactNode; }) { const [syncer] = useState( () => props.syncer ?? new NavigationSyncer(window.navigation), ); - const [contextValue] = useState(() => ({ - stores: props.stores ?? { - session: new StorageStore(globalThis.sessionStorage), - url: new URLStore(syncer), - }, - })); + const [stores] = useState(() => { + if (props.stores) { + return typeof props.stores === "function" + ? props.stores(syncer) + : props.stores; + } + return createDefaultStores(syncer); + }); useEffect(() => { - const stores = contextValue.stores; const abortController = new AbortController(); const { signal } = abortController; const applyAllStore = (callback: (store: Store) => void) => { @@ -52,10 +60,10 @@ export function LocationStateProvider({ ); return () => abortController.abort(); - }, [syncer, contextValue.stores]); + }, [syncer, stores]); return ( - + {children} ); From b746cc35dbc1bdf33ded59245ca909b7ccbea822 Mon Sep 17 00:00:00 2001 From: "akfm.sato" <01047245@CF0286.local> Date: Fri, 15 Sep 2023 17:49:15 +0900 Subject: [PATCH 3/4] fix context re render --- packages/location-state-core/src/provider.tsx | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/location-state-core/src/provider.tsx b/packages/location-state-core/src/provider.tsx index d94cb6d8..3de3b570 100644 --- a/packages/location-state-core/src/provider.tsx +++ b/packages/location-state-core/src/provider.tsx @@ -23,20 +23,19 @@ export function LocationStateProvider({ const [syncer] = useState( () => props.syncer ?? new NavigationSyncer(window.navigation), ); - const [stores] = useState(() => { - if (props.stores) { - return typeof props.stores === "function" - ? props.stores(syncer) - : props.stores; - } - return createDefaultStores(syncer); + // Generated on first render to prevent provider from re-rendering + const [contextValue] = useState(() => { + const stores = props.stores ?? createDefaultStores; + return { + stores: typeof stores === "function" ? stores(syncer) : stores, + }; }); useEffect(() => { const abortController = new AbortController(); const { signal } = abortController; const applyAllStore = (callback: (store: Store) => void) => { - Object.values(stores).forEach(callback); + Object.values(contextValue.stores).forEach(callback); }; const key = syncer.key()!; @@ -60,10 +59,10 @@ export function LocationStateProvider({ ); return () => abortController.abort(); - }, [syncer, stores]); + }, [syncer, contextValue.stores]); return ( - + {children} ); From f66630074a90aa548edc41c4e4013741d3313c9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=90=E8=97=A4=E6=98=AD=E6=96=87?= Date: Fri, 15 Sep 2023 21:00:01 +0900 Subject: [PATCH 4/4] export Stores,CreateStores,createDefaultStores --- packages/location-state-core/src/provider.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/location-state-core/src/provider.tsx b/packages/location-state-core/src/provider.tsx index 3de3b570..7c3d3340 100644 --- a/packages/location-state-core/src/provider.tsx +++ b/packages/location-state-core/src/provider.tsx @@ -4,10 +4,10 @@ import { NavigationSyncer } from "./syncers"; import { Syncer } from "./types"; import { ReactNode, useEffect, useState } from "react"; -type Stores = Record; -type CreateStores = (syncer: Syncer) => Stores; +export type Stores = Record; +export type CreateStores = (syncer: Syncer) => Stores; -const createDefaultStores: CreateStores = (syncer) => ({ +export const createDefaultStores: CreateStores = (syncer) => ({ session: new StorageStore(globalThis.sessionStorage), url: new URLStore(syncer), });