Ok, poznajemy dynamiczne komponenty w React + TypeScript. Kontynuacja lekcji poprzednich, zatem do dzieła!

Ok, mamy taki mega prosty komponent:

import {useState} from 'react';
import { ReactElement } from "react"

const Counter = () :ReactElement => {
    const [count, setCount] = useState<number>(0);

    return (
        <>
        <h1>Count is {count}</h1>
        <button onClick={() => setCount((prev) => prev + 1)}>+1</button>
        <button onClick={() => setCount((prev) => prev - 1)}>-1</button>
        </>
    )
}

export default Counter;

Dobra, tworzymy plik Private.tsx (już tsx nam podpowiada, że w folderze Components, piszemy RFC). Najpierw propsy:

type PrivateProps = {
    isLoggedIn: boolean;
    Component: React.ComponentType
};

Ważne – Component piszemy wielką literą. To właśnie takie rzeczy psują nam naukę. Na nich dostajemy największego szału.

Druga sprawa – gdybyśmy chcieli komponent o jakiś specyficznych propsach, zrobilibyśmy tak:

type PrivateProps = {
    isLoggedIn: boolean;
    Component: React.ComponentType<SomeProps>
};

W sumie możemy tak zrobić, bo nasz counter niczego nie przyjmuje:

type PrivateProps = {
    isLoggedIn: boolean;
    Component: React.ComponentType<{}>
};

Ok, teraz sam RFC:

type PrivateProps = {
    isLoggedIn: boolean;
    Component: React.ComponentType<{}>
};

export const Private = ({isLoggedIn, Component} : PrivateProps) => {
    if(isLoggedIn){
        return <Component/>;
    } else {
        return <p>Youre not logged in!</p>
    }
};

Ok, teraz w App.tsx importujemy i counter i private i używamy w ten sposób:

 <Private isLoggedIn={false} Component={Counter} />

Czyli po nazwie, ale bez JSX, bez znaków < >, w nawiasach {}. Sprawdzamy, czy działa. Wygląda na to, że tak.

To teraz zmieńmy isLoggedIn na true:

<Private isLoggedIn={true} Component={Counter} />

Nareszcie nam się wyświetla. Uff, nieźle. Tak wyglądają dynamic components z TypeScriptem.