I tried to convert a React app from Javascript to Typescript from code in youtube tutorial.
import 'swiper/swiper.min.css';
import './assets/boxicons-2.0.7/css/boxicons.min.css';
import './App.scss';
import { BrowserRouter, Route } from 'react-router-dom';
import Header from './components/header/Header';
import Footer from './components/footer/Footer';
import Routes from './config/Routes';
function App() {
return (
<BrowserRouter>
<Route
render={props => (
<>
<Header {...props} />
<Routes />
<Footer />
</>
)}
/>
</BrowserRouter>
);
}
export default App;
This is my Header code
import { useRef, useEffect } from 'react';
import { Link, useLocation } from 'react-router-dom';
import './header.scss';
import logo from '../../assets/tmovie.png';
const headerNav = [
{
display: 'Home',
path: '/'
},
{
display: 'Movies',
path: '/movie'
},
{
display: 'TV Series',
path: '/tv'
}
];
const Header = () => {
const { pathname } = useLocation();
const headerRef:any = useRef(null);
const active = headerNav.findIndex(e => e.path === pathname);
useEffect(() => {
const shrinkHeader = () => {
if (document.body.scrollTop > 100 || document.documentElement.scrollTop > 100) {
headerRef.current.classList.add('shrink');
} else {
headerRef.current.classList.remove('shrink');
}
}
window.addEventListener('scroll', shrinkHeader);
return () => {
window.removeEventListener('scroll', shrinkHeader);
};
}, []);
return (
<div ref={headerRef} className="header">
<div className="header__wrap container">
<div className="logo">
<img src={logo} alt="" />
<Link to="/">tMovies</Link>
</div>
<ul className="header__nav">
{
headerNav.map((e, i) => (
<li key={i} className={`${i === active ? 'active' : ''}`}>
<Link to={e.path}>
{e.display}
</Link>
</li>
))
}
</ul>
</div>
</div>
);
}
export default Header;
I use some package
@testing-library/jest-dom: 5.16.5
@testing-library/react: 14.0.0
@testing-library/user-event: 14.4.3
axios: 1.4.0
prop-types: 15.8.1
query-string: 8.1.0
react: 18.2.0
react-dom: 18.2.0
react-router-dom: 5.3.0
sass: 1.62.1
swiper: 6.8.4
More detail you can see my json Here my package.json
{
"name": "dummy",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^14.4.3",
"axios": "^1.4.0",
"prop-types": "^15.8.1",
"query-string": "^8.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^5.3.0",
"sass": "^1.62.1",
"swiper": "^6.8.4"
},
"devDependencies": {
"@types/react": "^18.0.37",
"@types/react-dom": "^18.0.11",
"@types/react-router-dom": "^5.3.3",
"@typescript-eslint/eslint-plugin": "^5.59.0",
"@typescript-eslint/parser": "^5.59.0",
"@vitejs/plugin-react": "^4.0.0",
"eslint": "^8.38.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.3.4",
"typescript": "^5.0.2",
"vite": "^4.3.9"
}
}
How to use Route
render
prop in Typescript?
The Header
component isn't actually consuming any props:
const Header = () => { // <-- NO PROPS
const { pathname } = useLocation();
const headerRef:any = useRef(null);
const active = headerNav.findIndex(e => e.path === pathname);
...
Header
is using the React hooks that have supplanted the older route props, in this case, specifically the useLocation
hook to access what was previously the props.location
prop value. Using the React hooks is now the preferred method.
Since no props consumed you should clean up the route and remove the passing through of route props.
function App() {
return (
<BrowserRouter>
<Route
render={() => (
<>
<Header />
<Routes />
<Footer />
</>
)}
/>
</BrowserRouter>
);
}
Or as a minor optimization, render the Header
, Routes
, and Footer
directly since they are rendered by a pathless route and unconditionally rendered anyway.
function App() {
return (
<BrowserRouter>
<Header />
<Routes />
<Footer />
</BrowserRouter>
);
}