Make LocalStorageProvider react to storage events (#55810)

This commit is contained in:
Oscar Kilhed 2022-09-27 14:37:59 +02:00 committed by GitHub
parent 4a4201ec92
commit 53a39e5037
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,4 +1,4 @@
import React, { PureComponent } from 'react'; import React, { useEffect, useState } from 'react';
import store from '../../store'; import store from '../../store';
@ -8,45 +8,42 @@ export interface Props<T> {
children: (value: T, onSaveToStore: (value: T) => void, onDeleteFromStore: () => void) => React.ReactNode; children: (value: T, onSaveToStore: (value: T) => void, onDeleteFromStore: () => void) => React.ReactNode;
} }
interface State<T> { export const LocalStorageValueProvider = <T,>(props: Props<T>) => {
value: T; const { children, storageKey, defaultValue } = props;
}
export class LocalStorageValueProvider<T> extends PureComponent<Props<T>, State<T>> { const [state, setState] = useState({ value: store.getObject(props.storageKey, props.defaultValue) });
constructor(props: Props<T>) {
super(props);
const { storageKey, defaultValue } = props; useEffect(() => {
const onStorageUpdate = (v: StorageEvent) => {
this.state = { if (v.key === storageKey) {
value: store.getObject(storageKey, defaultValue), setState({ value: store.getObject(props.storageKey, props.defaultValue) });
};
} }
};
onSaveToStore = (value: T) => { window.addEventListener('storage', onStorageUpdate);
const { storageKey } = this.props;
return () => {
window.removeEventListener('storage', onStorageUpdate);
};
});
const onSaveToStore = (value: T) => {
try { try {
store.setObject(storageKey, value); store.setObject(storageKey, value);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
} }
this.setState({ value }); setState({ value });
}; };
onDeleteFromStore = () => { const onDeleteFromStore = () => {
const { storageKey, defaultValue } = this.props;
try { try {
store.delete(storageKey); store.delete(storageKey);
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
this.setState({ value: defaultValue }); setState({ value: defaultValue });
}; };
render() { return <>{children(state.value, onSaveToStore, onDeleteFromStore)}</>;
const { children } = this.props; };
const { value } = this.state;
return <>{children(value, this.onSaveToStore, this.onDeleteFromStore)}</>;
}
}