Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use react-router-dom v5 render props using Typscript

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;

but I got error at this part enter image description here

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?

like image 730
Mind Mon Avatar asked Jun 09 '26 01:06

Mind Mon


1 Answers

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>
  );
}
like image 100
Drew Reese Avatar answered Jun 10 '26 15:06

Drew Reese