reactjs 如何使用Typscript使用react-router-dom v5渲染 prop

wvyml7n5  于 2023-06-22  发布在  React
关注(0)|答案(2)|浏览(107)

我试着从YouTube教程中的代码将React应用程序从JavaScript转换为Typescript。

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;

但我在此部分x1c 0d1x出错
这是我的标题代码

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;

我用一些 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
查询字符串:8.1.0
React:18.2.0
react-dom:18.2.0
react-router-dom:5.3.0
sass:1.62.1
刷卡器:6.8.4
更多细节你可以看到我的json这里我的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"
  }
}

如何在Typescript中使用Routerender prop?

3pmvbmvn

3pmvbmvn1#

您不能直接将...props作为属性传递给这里,因为这个文件和头组件之间存在类型不匹配,正如错误中提到的(history、location、match和staticContext)。你需要在header组件中设置正确的类型(例如,extend intrinsicAttributes),如:

interface HeaderProps extends React.HTMLAttributes<HTMLElement> {
  history: History<unknown>;
  location: Location<unknown>;
  match: match<{ [x: string]: string | undefined; }>;
  staticContext?: StaticContext | undefined;
}

function Header(props: HeaderProps) {
  ...
}
s1ag04yj

s1ag04yj2#

Header组件实际上并没有消耗任何props:

const Header = () => { // <-- NO PROPS
  const { pathname } = useLocation();
  const headerRef:any = useRef(null);

  const active = headerNav.findIndex(e => e.path === pathname);

  ...

Header正在使用React hook,取代了旧的route props,在本例中,特别是useLocation hook来访问以前的props.location prop值。使用React钩子现在是首选方法。
由于没有消耗 prop ,你应该清理路线,并删除路线 prop 的通过。

function App() {
  return (
    <BrowserRouter>
      <Route
        render={() => (
          <>
            <Header />
            <Routes />
            <Footer />
          </>
        )}
      />
    </BrowserRouter>
  );
}

或者作为一个小优化,直接渲染HeaderRoutesFooter,因为它们是通过无路径路由渲染的,而且无论如何都是无条件渲染的。

function App() {
  return (
    <BrowserRouter>
      <Header />
      <Routes />
      <Footer />
    </BrowserRouter>
  );
}

相关问题