首页 > 解决方案 > 使用 React(本地存储)仅显示一次 Popup

问题描述

我想用 React Hooks 只显示一次弹出窗口。

  1. 首次访问example.com/campaign/1234
  2. 显示弹出窗口
  3. 关闭或刷新页面。
  4. 再次访问example.com/campaign/1234并且不显示弹出窗口
  5. 第一次访问example.com/campaign/0000(是不同的 URL)
  6. 显示弹出窗口
  7. 关闭或刷新页面
  8. 再次访问example.com/campaign/0000orexample.com/campaign/1234并且没有显示弹出窗口

知道怎么做吗?我知道我需要使用local storage,但是当用户关闭或刷新页面时如何触发事件?

这是一个沙盒

我也读过这个线程,但它没有提到如何使用 Hooks

标签: javascriptreactjslocal-storage

解决方案


如果您从不使用setStickyState自定义挂钩的回调,则状态将保持在其初始值。

它似乎setStickyState也有一个错误,如果密钥已更改,它将不会更新。这是我称之为的增强版本useLocalStorage,它应该更可靠地工作:

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];
}

然后你可以像这样使用它:

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>

这是一个演示(使用 TypeScript):

useLocalStorage演示


推荐阅读