Reuse useTypedEventEmitterState in useLocalStorage

This commit is contained in:
Robin
2025-06-04 17:50:35 -04:00
parent 0728bb094a
commit d6985e2d06

View File

@@ -5,13 +5,18 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details. Please see LICENSE in the repository root for full details.
*/ */
import EventEmitter from "events"; import { useCallback } from "react";
import { useCallback, useSyncExternalStore } from "react"; import { TypedEventEmitter } from "matrix-js-sdk";
import { useTypedEventEmitterState } from "./useEvents";
type LocalStorageItem = ReturnType<typeof localStorage.getItem>; type LocalStorageItem = ReturnType<typeof localStorage.getItem>;
// Bus to notify other useLocalStorage consumers when an item is changed // Bus to notify other useLocalStorage consumers when an item is changed
export const localStorageBus = new EventEmitter(); export const localStorageBus = new TypedEventEmitter<
string,
{ [key: string]: () => void }
>();
/** /**
* Like useState, but reads from and persists the value to localStorage * Like useState, but reads from and persists the value to localStorage
@@ -21,18 +26,11 @@ export const localStorageBus = new EventEmitter();
export function useLocalStorage( export function useLocalStorage(
key: string, key: string,
): [LocalStorageItem, (value: string) => void] { ): [LocalStorageItem, (value: string) => void] {
const subscribe = useCallback( const value = useTypedEventEmitterState(
(onChange: () => void) => { localStorageBus,
localStorageBus.on(key, onChange); key,
return (): void => { useCallback(() => localStorage.getItem(key), [key]),
localStorageBus.off(key, onChange);
};
},
[key],
); );
const getValue = useCallback(() => localStorage.getItem(key), [key]);
const value = useSyncExternalStore(subscribe, getValue);
const setValue = useCallback( const setValue = useCallback(
(newValue: string) => setLocalStorageItemReactive(key, newValue), (newValue: string) => setLocalStorageItemReactive(key, newValue),
[key], [key],
@@ -46,5 +44,5 @@ export const setLocalStorageItemReactive = (
value: string, value: string,
): void => { ): void => {
localStorage.setItem(key, value); localStorage.setItem(key, value);
localStorageBus.emit(key, value); localStorageBus.emit(key);
}; };