-
Notifications
You must be signed in to change notification settings - Fork 20
Fix: Cached Data Shown After Logout and Re-login #4040
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,8 @@ import Qrcode from '@components/qrCode/Qrcode' | |
| import BottomModalScan from '@components/BottomModal/BottomModalScan' | ||
| import BecknButton from '@beckn-ui/molecules/src/components/button/Button' | ||
| import TopSheet from '@components/topSheet/TopSheet' | ||
| import { useDispatch } from 'react-redux' | ||
| import { logoutUser } from '@utils/logout' | ||
|
|
||
| type PathnameObjectType = { [key: string]: string } | ||
|
|
||
|
|
@@ -137,9 +139,8 @@ const TopHeader: React.FC<TopHeaderProps> = ({ handleMenuClick }) => { | |
| w={'20px'} | ||
| h={'20px'} | ||
| onClick={() => { | ||
| const user = localStorage.getItem('userPhone') as string | ||
| localStorage.clear() | ||
| localStorage.setItem('userPhone', user) | ||
| const dispatch = useDispatch() | ||
| logoutUser(dispatch, router) | ||
| router.push(`/homePage`) | ||
| }} | ||
| src="/images/Home_icon.svg" | ||
|
|
@@ -179,6 +180,20 @@ const TopHeader: React.FC<TopHeaderProps> = ({ handleMenuClick }) => { | |
| /> | ||
| {t['orderHistory']} | ||
| </Box> | ||
| <Box | ||
| onClick={() => { | ||
| const dispatch = useDispatch() | ||
| logoutUser(dispatch, router) | ||
| setMenuModalOpen(false) | ||
| }} | ||
| className={styles.top_header_modal} | ||
| > | ||
| <Image | ||
| src="/images/logout.svg" | ||
| alt="Logout icon" | ||
| /> | ||
| Logout | ||
| </Box> | ||
|
Comment on lines
+183
to
+196
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Incorrect usage of useDispatch hook in Logout menu item Similar to the home icon issue, useDispatch is being called inside an event handler. Additionally, the menu item's behavior conflicts with the logout utility's redirect. + const dispatch = useDispatch()
<Box
onClick={() => {
- const dispatch = useDispatch()
logoutUser(dispatch, router)
setMenuModalOpen(false)
}}
className={styles.top_header_modal}
>Consider removing
|
||
| </BottomModal> | ||
| </> | ||
| ) | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,42 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import axios, { AxiosRequestConfig } from 'axios' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Fetch utility with proper cache control headers | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param url The URL to fetch | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param options Additional axios request options | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @returns Promise with the axios response | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const fetchWithCacheControl = async (url: string, options: AxiosRequestConfig = {}) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const defaultHeaders = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'Cache-Control': 'no-cache, no-store, must-revalidate', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Pragma: 'no-cache', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Expires: '0' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const requestOptions: AxiosRequestConfig = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ...options, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| headers: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ...defaultHeaders, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ...options.headers | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return axios(url, requestOptions) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Adds cache control headers to all axios requests | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const setupAxiosInterceptors = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| axios.interceptors.request.use(config => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Add cache control headers to all requests | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| config.headers = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ...config.headers, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'Cache-Control': 'no-cache, no-store, must-revalidate', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Pragma: 'no-cache', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Expires: '0' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return config | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+30
to
+42
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Prevent adding multiple identical interceptors. If +let isInterceptorSetup = false;
export const setupAxiosInterceptors = () => {
+ if (isInterceptorSetup) return;
+
axios.interceptors.request.use(config => {
// Add cache control headers to all requests
config.headers = {
...config.headers,
'Cache-Control': 'no-cache, no-store, must-revalidate',
Pragma: 'no-cache',
Expires: '0'
}
return config
})
+
+ isInterceptorSetup = true;
}📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| import { userInfoActions } from '../store/user-slice' | ||
| import Cookies from 'js-cookie' | ||
| import { NextRouter } from 'next/router' | ||
| import { Dispatch } from '@reduxjs/toolkit' | ||
|
|
||
| /** | ||
| * Comprehensive logout utility that clears all user data and caches | ||
| * @param dispatch Redux dispatch function | ||
| * @param router Next.js router | ||
| */ | ||
| export const logoutUser = (dispatch: Dispatch<any>, router: NextRouter) => { | ||
| // Clear Redux state | ||
| dispatch(userInfoActions.userLogout()) | ||
|
|
||
| // Clear cookies | ||
| Cookies.remove('userInfo') | ||
| Cookies.remove('authToken') | ||
|
|
||
| // List of localStorage keys to preserve (if needed) | ||
| const keysToPreserve = ['userPhone'] | ||
| const preservedData: Record<string, string | null> = {} | ||
|
|
||
| // Save data that needs to be preserved | ||
| keysToPreserve.forEach(key => { | ||
| preservedData[key] = localStorage.getItem(key) | ||
| }) | ||
|
|
||
| // Clear all localStorage | ||
| localStorage.clear() | ||
|
|
||
| // Restore preserved data | ||
| Object.entries(preservedData).forEach(([key, value]) => { | ||
| if (value) localStorage.setItem(key, value) | ||
| }) | ||
|
|
||
| // Clear session storage | ||
| sessionStorage.clear() | ||
|
|
||
| // Redirect to login page | ||
| router.push('/') | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect usage of useDispatch hook in event handler
The useDispatch hook is being called inside an event handler, which violates React's rules of hooks. Hooks should only be called at the top level of your component.