Hello,
We are in the middle of integrating AWS Cognito to our React App and encountered an issue where component state does not seem to reset after navigating to a route.
The app is created with:
- Create React App (with Typescript)
- aws-amplify/ui-react": "^6.1.5"
- "aws-amplify": "^6.0.19"
- "react": "^18.2.0"
- "react-router-dom": "^6.22.2"
Steps to reproduce:
- User signs in using AWS Cognito + Amplify UI (withAuthenticator component)
- User search for a keyword, this is where states dont seem to reset
It works fine when you enter the keyword in the URL bar (refreshes page), but not when entering the keyword on the search bar.
working code:
App. tsx
Amplify.configure(config)
export function App({ user }: WithAuthenticatorProps) {
return (
<BrowserRouter>
<Routes>
<Route
element={
<>
<NavBar user={user} />
<div style={{ position: 'relative', minHeight: `calc(100vh - 135px)` }}>
<Outlet />
</div>
</>
}
>
<Route path='/' element={<Home />} />
<Route
path='/my-page/:mySearch'
element={<MyPage key={window.location.pathname} />}
/>
</Route>
</Routes>
</BrowserRouter>
)
}
export default withAuthenticator(App, { hideSignUp: true })
Navbar.tsx
/* eslint-disable @typescript-eslint/no-unused-vars */
import {
AppBar,
Container,
Toolbar,
} from '@mui/material'
import Search from './Search'
function NavBar(user: any) {
return (
<AppBar
position='static'
sx={{
position: 'sticky',
top: 0,
width: '100%',
zIndex: 2,
}}
>
<Container maxWidth='xl'>
<Toolbar disableGutters>
<Search />
</Toolbar>
</Container>
</AppBar>
)
}
export default NavBar
Search.tsx
const Search = () => {
const navigate = useNavigate()
const handleKeyDown = (event: any) => {
if (event.key === 'Enter') {
navigate(`/my-page/${event.target.value}`)
}
}
return (
<Search>
<SearchIconWrapper>
<SearchIcon />
</SearchIconWrapper>
<StyledInputBase
autoComplete='off'
placeholder='Search'
inputProps={{ 'aria-label': 'search' }}
id='search'
onKeyDown={handleKeyDown}
/>
</Search>
)
}
export default Search
MyPage.tsx
/* eslint-disable @typescript-eslint/no-unused-vars */
import React, { useState, useEffect } from 'react'
import { useLocation, useParams } from 'react-router-dom'
import { Box} from '@mui/material'
import Loading from './Loading'
const MyPage = () => {
const location = useLocation()
const [showLoading, setLoading] = useState(true) // this state is not resetting to true
console.log(showLoading, 'showLoading')
useEffect(() => {
console.log('MyPage useEffect')
setTimeout(() => {
setLoading(false)
}, 5000)
}, [location.pathname])
return (
<Box
sx={{
p: 4,
marginLeft: '-32px',
paddingBottom: '120px',
}}
>
{showLoading && <Loading />}
{!showLoading && (
<p>not loading</p>
)}
</Box>
)
}
export default MyPage
index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: <https://bit.ly/CRA-vitals>
reportWebVitals();