Reputation: 6788
I would like to show the popup only one time with React Hooks.
example.com/campaign/1234
example.com/campaign/1234
and don't show popupexample.com/campaign/0000
(is a different URL)example.com/campaign/0000
or example.com/campaign/1234
and the popup is not being displayedAny idea of how to do it? I know that I need to use local storage
but how can I trigger the event when the user closes or refreshes the page?
Here is a sandbox.
I also read this thread but it doesn't mention how to do it with Hooks
Upvotes: 1
Views: 2835
Reputation: 5926
If you never use the setStickyState
callback from the custom hook, the state will just remain at its initial value.
It seems like setStickyState
also has a bug in it, where it won't update if the key has changed. Here's an enhanced version that I've called useLocalStorage
, which should work more reliably:
export function useLocalStorage(key, initialDefault) {
const [val, setVal] = useState(() => {
const localStorageVal = localStorage.getItem(key);
return localStorageVal !== null
? JSON.parse(localStorageVal)
: initialDefault;
});
useEffect(() => {
if (localStorage.getItem(key) === null) {
setVal(initialDefault);
}
}, [key, initialDefault]);
useEffect(() => {
localStorage.setItem(key, JSON.stringify(val));
}, [val, key]);
return [val, setVal];
}
You can then use it like this:
const [visited, setVisited] = useLocalStorage(pageId, false);
const navigateAway = useCallback(() => {
setVisited(true)
}, [setVisited])
useEffect(() => {
// if user navigates away to a completely different site
// or refreshes the page etc
window.addEventListener("beforeunload", navigateAway);
// if user navigates to another page on the same site
return () => {
navigateAway();
window.removeEventListener("beforeunload", navigateAway);
};
}, [pageId, navigateAway]);
// ...
<dialog open={!visited}>
<p>Welcome to page {pageId}!</p>
<button onClick={() => setVisited(true)}>
Don't show again on this page
</button>
</dialog>
Here's a demo (with TypeScript):
Upvotes: 2