网站搜索

javascript - 对 JSX.Element 与 React.Component 之间的区别以及在 React-dom-router 中何时使用它们感到困惑


我正在开始一个新的 react-typescript 项目,并且我正在使用 react-router-dom 来管理路由,但我在浏览器计数器中遇到了以下错误:

Matched leaf route at location "/restaurant" does not have an element. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page

这是代码:

    <BrowserRouter>
                    <SiteNav hasItemInCart={false} numberOfItemsInCart={0}/>
                    <Routes>
                        <Route path="/home" children={Home} />
                        <Route path="/restaurant" children={Restaurant} />
                        <Route path="/hostel" children={Hostel} />
                    </Routes>
                </BrowserRouter>

export default class Home extends Component<any, any> {
    render() {
        return (
            <>
                <div>
                    Home
                </div>
            </>
        )
    }
}
class Hostel extends React.Component<any, any> {
    render() {
        return (
            <div className="Hostal">
                <body>Hostal</body>
            </div>
        );
    }
}

据我理解,我应该返回一个 JSX.element,但当我尝试使用它时,TypeScript 抛出了错误。我为什么不能使用 React.Component?我应该如何改为这样做?

答案#1

JSX.Element 是已 渲染 的 JSX 的类型。例如:

const a: JSX.Element = <>asd</>
const b: JSX.Element = <SomeComponent />

React.Component 是一种组件类型,它知道如何在使用特定 props 渲染时生成 JSX.Element。

function A() { return <>Testing</> } // A is a component
const a: JSX.Element = <A />

通常,React 中的 children 是一个 JSX.Element,你作为标签的内容传入。

<A>
  <div>children go here</div>
</A>

或者你可以显式地使用 children 属性:

<A children={<div>children go here</div>} />

所以在你的情况下,你传递了一个组件给一个期望渲染内容的属性。

如果你想传入渲染后的内容,你需要以下之一:

<Route path="/home" children={<Home />} />

或者:

<Route path="/home"><Home/></Route>

尽管现代版本的 React Router 建议将 JSX 传递给 element 属性,所以除非你使用的是旧版本,否则请使用这个方法。

<Route path="/home" element={<Home />} />

答案#2

我认为你把 React 类型和 Route 组件的 API 混淆了。在 react-router-dom@6 中,现在只有一个 element 属性(没有 component 或 render/children 函数属性),它接受一个 React.ReactNode,也就是 任何有效的 JSX。

路线与路线

declare function Route(
  props: RouteProps
): React.ReactElement | null;

interface RouteProps {
  caseSensitive?: boolean;
  children?: React.ReactNode;
  element?: React.ReactNode | null;
  index?: boolean;
  path?: string;
}

您正在使用 RRDv5 Route 组件的 API/语法,将您的路由组件传递给 Route。请将您的路由转换为使用 element 属性。

示例:

<BrowserRouter>
  <SiteNav hasItemInCart={false} numberOfItemsInCart={0} />
  <Routes>
    <Route path="/home" element={<Home />} />
    <Route path="/restaurant" element={<Restaurant />} />
    <Route path="/hostel" element={<Hostel />} />
  </Routes>
</BrowserRouter>