首页 > 解决方案 > 在页面刷新时,会话存储如何工作?

问题描述

我想在单击添加按钮时显示一个对话框。并且在单击隐藏按钮时不为会话显示它(使用会话存储)。

下面是我的代码,

function Parent() {
    const DialogRequest = useDialogRequest();
    const onAdd = () => {
        DialogRequest(true);
    }
    render = () => {
        return (
            <button onClick={onAdd}>Add</button>
        );
    }
}

函数 Dialog(onHide) { return( {showDialog? hide : null } ); }

const dialogRequestContext = React.createContext<ContextProps>({});

export const DialogRequestProvider = ({ children }: any) => {
    const [showDialog,setShowDialog] = React.useState(false);

    const onHide = () => {
        setDialogOpen(false);
    };
    const setDialogOpen = (open: boolean) => {
        if (open) {
            const sessionDialogClosed = sessionStorage.getItem('dialog');
            if (sessionDialogClosed !== 'closed') {
                setShowDialog(open);
                sessionStorage.setItem('dialog', 'closed');
            }
        } else {
            setShowDialog(open);
        }
    };
    return (
        <DialogContext.Provider
            value={{ setDialogOpen }}
        >
            {children}
            <Dialog onHide={onHide}
                showDialog={showDialog}
            />
        </DialogContext.Provider>
    );
};



export function useDialogRequest() {
    const dialogRequestContext = React.useContext(
        dialogRequestContext
    );


    return function DialogRequest(open: boolean) {
        if (dialogRequestContext &&
            dialogRequestContext.setDialogOpen
        ) {
            dialogRequestContext.setDialogOpen(open);
          }
    };
}

此代码有效。但是当页面重新加载时,即使在页面重新加载之前未单击隐藏消息,对话框也不会再次打开。

我试图在页面重新加载后控制台记录对话框的值,如下所示。

if (open) {
    const sessionDialogClosed = sessionStorage.getItem('dialog');
    console.log('sessiondialogclosed', sessionDialogClosed); //this gives closed 
    if (sessionDialogClosed !== 'closed') {
        setShowDialog(open);
        sessionStorage.setItem('dialog', 'closed');
    }
} else {
    setShowDialog(open);
}

即使我在页面重新加载之前点击了隐藏按钮.....这给了我关闭会话存储项对话框的输出。

不确定这是否是它应该表现的方式。如果没有,有人可以帮我解决这个问题以使其正确。

谢谢。

标签: javascriptreactjstypescript

解决方案


正如我在评论中所表达的:

useState 中的值会在页面的整个生命周期内保持不变。它们不会在页面刷新时保留。如果你需要这样做,你可以考虑创建一个包装 useState 的钩子,它将值保存到 localStorage 中,然后在页面加载时检索初始值。

这是这种钩子的一个基本示例。

function usePersistentState(defaultValue, key) {
  let initVal;
  try {
    initVal = JSON.parse(localStorage.getItem(key));
  } catch {}
  if (initVal === undefined) initVal = defaultValue;

  const [state, setState] = useState(initVal);
  function persistState(value) {
    if (typeof value === "function") value = value(state);
    localStorage.setItem(key, JSON.stringify(value));
    setState(value);
  }
  return [state, persistState];
}

这是它如何工作的示例。如果您在切换值后刷新页面,它将从 恢复之前的状态localStorage

关于它的工作原理有一些注意事项。如果你有一个非常复杂的状态,你不应该使用它,你应该做基本相同的事情,但使用useReducer代替。但在这样一个简单的例子中应该没问题。


推荐阅读