Here is a brief description of the structure of the problem. I have a main navbar (Navbar), some links (NavLinks), and a side panel (this is rendered inside Navbar to make things easier).
// Navbar.tsx
const Navbar = () => {
const userID = "some-userID";
const [ActivePanel, setActivePanel] = useState<React.ComponentType | null>(
null
);
return (
<>
<header className="sticky top-0 flex items-center justify-between p-10 ">
<p>Logo Component</p>
<NavLinks setActivePanel={setActivePanel} />
</header>
{ActivePanel && (
<div className="absolute top-0 left-0 w-full h-screen bg-amber-100/50 backdrop-blur-[2px]">
<div className="fixed top-0 right-0 min-w-[350px] min-h-screen flex flex-col gap-2 p-5 bg-amber-200 shadow-sm">
<button
onClick={() => setActivePanel(null)}
className="mb-2 text-sm text-gray-500"
>
close
</button>
{ActivePanel}
</div>
</div>
)}
</>
);
};
// NavLinks.tsx
interface Props {
setActivePanel: React.Dispatch<React.SetStateAction<React.ComponentType| null>>;
}
const NavLinks = ({ setActivePanel }: Props) => {
return (
<div className="flex items-center gap-5">
{NAV_ITEMS.map((item) => (
<button
key={item.text}
onClick={() => setActivePanel(item.panelComponent)}
className="cursor-pointer flex items-center gap-2 p-2"
>
{item.text}
</button>
))}
</div>
);
};
// NAV_ITEMS.ts
import PanelOne from "@/components/sidePanels/PanelOne";
import PanelTwo from "@/components/sidePanels/PanelTwo";
import PanelThree from "@/components/sidePanels/PanelThree";
export const NAV_ITEMS = [
{
text: "Panel One",
panelComponent: PanelOne,
},
{
text: "Panel Two",
panelComponent: PanelTwo,
},
{
text: "Panel Three",
panelComponent: PanelThree,
}
];
This works fine, even though if you hover over ActivePanel, it will give you this problem:
Type 'ComponentType<{}>' is not assignable to type 'ReactNode'.
Problem: Even though this works, I am actually trying to pass userID, which will ultimately come from useSession from 'next-auth/react', as a prop to the active panel.
Is there a way to render the panel dynamically while passing a prop.
Thank you
Edit:
I made changes to a lot of things.
- I changed useState in Navbar to
const [ActivePanel, setActivePanel] = useState<React.ComponentType<{userID: string;}> | null>(null);
- I changed Interface and onClick in NavLinks to
interface Props {
setActivePanel: React.Dispatch<React.SetStateAction<React.ComponentType
<{ userID: string}> | null>>;
}
onClick={() => {
setActivePanel(() => item.panelComponent)
}
Now it is working fine.