ค้นหาเว็บไซต์

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 คือประเภทของคอมโพเนนต์ที่รู้วิธีสร้าง JSX.Element เมื่อถูกเรนเดอร์ด้วย props เฉพาะ

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

โดยปกติแล้ว children ใน React คือ JSX.Element ที่คุณส่งเป็นเนื้อหาของแท็ก

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

หรือคุณสามารถใช้ prop 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 กับ API ของคอมโพเนนต์ Route ใน react-router-dom@6 ตอนนี้มีแค่ prop element เท่านั้น (ไม่มี prop 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;
}

คุณกำลังส่งคอมโพเนนต์ที่กำหนดเส้นทางของคุณไปยัง Route โดยใช้ API/ไวยากรณ์คอมโพเนนต์ Route ของ RRDv5 แปลงเส้นทางของคุณให้ใช้พร็อพ 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>