我正在为我的网站制作 GDPR 横幅。我希望这个横幅出现在我网站的每一页上,直到用户点击接受按钮。在我的 Gatsby 站点中,我使用 Context API 来存储用户是否接受了带有名为 GDPR_Accepted 的本地存储状态的条款。我将其初始化为 false,当用户单击 GDPR 横幅中的接受按钮时,我将其切换为 true。设置为 true 后,GDPR 横幅不应显示在任何页面上。
我可以使用此功能,除非当用户离开我的网站并返回时 GDPR_Accepted 重置为 false,即使用户之前已接受这些条款,GDPR 横幅也会再次显示。为什么 localStorage 在用户离开时不持久化数据?
这是我处理 GDPR_Accepted 状态的 Context API 代码:
function reducer(state, action) {
switch(action.type) {
case TOGGLE_GDPR: {
return {
...state,
GDPR: state.GDPR === false ? true : false
}
}
default: {
return {
...state
}
}
}
}
export const GlobalContextProvider = ({ children }) => {
const [state, dispatch] = React.useReducer(reducer, initialState)
useEffect(() => {
if (storageAvailable('localStorage')) {
localStorage.setItem('GDPR_Accepted', state.GDPR)
}
else {
return 0;
}
}, [state])
return (
<GlobalStateContext.Provider value={state}>
<GlobalDispatchContext.Provider value={dispatch}>
{children}
</GlobalDispatchContext.Provider>
</GlobalStateContext.Provider>
)
}
我也有从 MDN 文档中获取的这个函数,它首先检查本地存储是否可用:
// Checks if localStorage is available in the user's browser
function storageAvailable(type) {
var storage;
try {
storage = window[type];
var x = '__storage_test__';
storage.setItem(x, x);
storage.removeItem(x);
return true;
}
catch(e) {
return e instanceof DOMException && (
// everything except Firefox
e.code === 22 ||
// Firefox
e.code === 1014 ||
// test name field too, because code might not be present
// everything except Firefox
e.name === 'QuotaExceededError' ||
// Firefox
e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
// acknowledge QuotaExceededError only if there's something already stored
(storage && storage.length !== 0);
}
}
在我的前端,我有一个组件来显示实际出现的 GDPR 横幅,在这个组件中,我切换了存储在 localStorage 中的 GDPR_Accepted 状态:
<Button className={styles.acceptButton} onClick={async () => {
dispatch({ type: "TOGGLE_GDPR" })
}}>Accept All Cookies</Button>
然后,在我的布局组件中,我使用三元组来决定是否应显示 GDPR 横幅。我从 Context API const state = useContext(GlobalStateContext);
访问状态,然后使用三元:
{
state.GDPR === false ?
<GDPR />
: null
}
所有这些都有效,但我遇到了在用户离开和回来时保持状态的问题。我想到的一些可能的问题:
window
甚至 localStorage
)在 Gatsby 构建时由于 SSR 会引发错误。我在使用 localStorage
时没有遇到这个问题,这很奇怪。localStorage
应该只存储 strings,但是当我在 localStorage
中存储 strings 时,我的 GDPR 横幅无法工作.如果我使用 boolean,我只能让它工作。出于某种原因,布尔值有效,但字符串无效。localStorage
吗?如果是这样,怎么办?答案 0 :(得分:0)
看起来 GlobalContextProvider 定义中的 useEffect
钩子正在重置 localStorage 键的值。每次安装组件(即每个页面加载)时,此函数都会(至少)运行。无需在每次页面加载时初始化 localStorage 键。您调用 setItem
的唯一位置应该是按钮的 onClick
。