Lewis
Lewis

Reputation: 175

Next.js - how to change the component that is displayed?

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

Answers (2)

hhhhhhh
hhhhhhh

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

Elihu Del Valle
Elihu Del Valle

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

Related Questions