Reputation: 175
I'm brand new to React/Nextjs.
I'm using this as a template: https://ui.mantine.dev/component/navbar-simple
This is the example data:
const data = [
{ link: '/notifications', label: 'Notifications', icon: IconBellRinging },
{ link: '/billing', label: 'Billing', icon: IconReceipt2 },
{ link: '/security', label: 'Security', icon: IconFingerprint },
It is used to built a navbar:
export function NavbarSimple() {
const { classes, cx } = useStyles();
const [active, setActive] = useState('Billing');
const links = data.map((item) => (
<a
className={cx(classes.link, { [classes.linkActive]: item.label === active })}
href={item.link}
key={item.label}
onClick={(event) => {
event.preventDefault();
setActive(item.label);
}}
>
<item.icon className={classes.linkIcon} stroke={1.5} />
<span>{item.label}</span>
</a>
));
return (
<AppShell
<Navbar>
<Navbar.Section>
{links}
</Navbar.Section>
</Navbar>
>
{/*
I am trying to get the components to be swapped/updated here
*/}
</AppShell>
Goal: If someone clicks "Security" in the navbar, the Security component will load.
Let's say I have built the "Notifications", "Billing" and "Security" components. To update DOM, I saw a guide for using react-router-dom to do this. But I am trying to stick with only Nextjs.
Whatever string is stored in "link" can be changed. But from the "link" in the data object, is there a way to update the component? If someone can point me to a tutorial, example, or even what to search for, I'd greatly greatly appreciate it :) I've been researching this evening but have not found anything yet.
I also made a codesandbox: https://wytec9.csb.app/
Upvotes: 0
Views: 861
Reputation: 441
You could achieve this by modifying your current data array of objects, and adding a component corresponding to each link.
Here is what it would looks like
const data = [
{ link: '/notifications', label: 'Notifications', icon: IconBellRinging, component: <Notification /> },
{ link: '/billing', label: 'Billing', icon: IconReceipt2, component: <Billing /> },
{ link: '/security', label: 'Security', icon: IconFingerprint, component: <Security /> }
]
Create a state that will store the component (you could modify your active
state to be an object containing both the label and object):
const [activeComponent, setActiveComponent] = useState(null);
Then, update it in your onClick.
<a
className={cx(classes.link, { [classes.linkActive]: item.label === active })}
href={item.link}
key={item.label}
onClick={(event) => {
event.preventDefault();
setActive(item.label);
setActiveComponent(item.component)
}}
>
<item.icon className={classes.linkIcon} stroke={1.5} />
<span>{item.label}</span>
</a>
Good, you then can render the active component where you need it:
<AppShell
<Navbar>
<Navbar.Section>
{links}
</Navbar.Section>
</Navbar>
>
{activeComponent}
</AppShell>
Upvotes: 1
Reputation: 406
You could have within this component a function that will bring the component you want depending on the value, a quick example for this:
const renderComponent = () => {
if(active === 'Billing'){
return <Billing/>
} else if (){
// you get the idea
}
}
Now call that function to bring up the right component:
return (
<AppShell
<Navbar>
<Navbar.Section>
{links}
</Navbar.Section>
</Navbar>
>
{renderComponent()}
</AppShell>
Upvotes: 1