我有一个可供用户加入的大厅。为了在页面刷新上将已加入的大厅保留在客户端上,我决定将已加入的大厅放入浏览器的会话存储中。在此之前,useState
不会通过页面刷新保持不变。
据我所知,“设置会话存储”被归类为副作用,应在useEffect
中进行处理。问题是当我设置大厅时,将大厅作为从属关系的useEffect
无法运行。
设置断点表明它根本没有运行,但是我可以看到joinedLobby
已从undefined
更改为对象(示例:{success: "Successfully joined ...", payload : { id:"", ...}}
)。
会话存储区为空。
const { setJoinedLobby } = useContext(JoinedLobbyProviderContext);
const history = useHistory();
useEffect(() => {
if (joinState.result === undefined) return;
setJoinedLobby(joinState.result);
history.push('/lobby');
}, [joinState.result, history, setJoinedLobby]);
<JoinedLobbyProviderContext.Provider
value={{ getJoinedLobby, setJoinedLobby }}>
<Route path='/play'>
<Play />
</Route>
<Route path='/lobby'>
<Lobby />
</Route>
</JoinedLobbyProviderContext.Provider>
const [joinedLobby, setJoinedLobby] = useState(undefined);
useEffect(() => {
if (joinedLobby === undefined) return;
sessionStorage.setItem('joinedLobby', JSON.stringify(joinedLobby));
}, [joinedLobby]);
const getJoinedLobby = () => {
return JSON.parse(sessionStorage.getItem('joinedLobby'));
};
const joinInit = {
errors: undefined,
loading: false,
result: undefined,
id: undefined,
};
const joinReducer = (state, action) => {
switch (action.type) {
case 'joinLobby': {
return { ...state, id: action.payload };
}
case 'loadingTrue':
return { ...state, loading: true };
case 'setResult':
return { ...state, loading: false, result: action.payload };
case 'setErrors':
return {
...state,
loading: false,
errors: action.payload,
};
case 'reset':
return joinInit;
default : {throw new Error('Didn't find action passed to reducer')}
}
};
const [joinState, joinStateDispatch] = useReducer(joinReducer, joinInit);
const passRef = useRef();
useEffect(() => {
const joinLobby = async () => {
joinStateDispatch({ type: 'loadingTrue' });
try {
const jsonResponse = await (
await fetch(`${BACKEND_URL}/play/joinLobby/${joinState.id}`, {
method: 'PATCH',
credentials: 'include',
headers: {
'Content-type': 'application/json',
},
body: JSON.stringify({
password: passRef.current.value,
}),
})
).json();
joinStateDispatch({ type: 'setResult', payload: jsonResponse });
} catch (e) {
joinStateDispatch({ type: 'setErrors', payload: e });
}
};
if (joinState.id !== undefined) {
joinLobby();
}
}, [joinState.id, joinStateDispatch]);
会话存储仅应用于存储与会话相关的数据,并且由于大小限制,它可能不存储值,请使用localStorage。它为您提供了巨大的4MB大小。您可以通过将对象数组转换为字符串来设置数据,如下所示:-
localStorage.setItem("joinState", JSON.stringify(joinState));
您可以按以下方式获取对象数组:-
JSON.parseJSON(localStorage.getItem("joinState"));
我希望这对您有帮助...