skip to Main Content

So I am trying to make my code more modular but I am struggling here so I have a tab bar and based on what nav/tab item is clicked I want to render a certain component I can’t seem to figure out how to pass the props properly in order to do such as right now my code is just saying that the children value is the label value for the tab rather than the component I am passing?

component with tab bar inside it:

return (
   <div>
  <NavBar
            items={[
              { label: 'Home', children: <Home/> onClick: () => handleTabClick('Home') },
              { label: 'Profile', children: <ProfileComponent/>, onClick: () => handleTabClick('Profile') }
            ]}
          />

  </div>
)

here is my navbar/tab bar component:

import React from 'react';
import { useState } from 'react';

const NavBar = ({ items }) => {
    return (
        <nav className="border-b mb-4">
            <ul className="flex space-x-6 p-4"> {/* Added list-none class */}
                {items.map((item, index) => (
                    <NavItem key={index} children={item.children} label={item.label} href={item.href}>
                        {item.label}
                    </NavItem>
                ))}
            </ul>
        </nav>
    );
};

const NavItem = ({ label, href, children }) => {
    const [isActive, setIsActive] = useState(false);

    const handleClick = () => {
        setIsActive(true);
    };
    console.log("children = ", children);
    return (
        <li>
            <a href={href} className={`text-blue-600 hover:text-blue-800 ${isActive ? 'active' : ''}`} onClick={handleClick}>
                {label}
            </a>
            {isActive && children}
        </li>
    );
};

export default NavBar;

3

Answers


  1. Looks like there’s a few bugs that if corrected should solve your issue:

    1. To pass the children prop correctly in the NavItem component…Instead of passing it directly as a prop, you should use it as a child element of NavItem
    2. To handle the onClick event properly in your NavItem component…You need to call the onClick function passed from the NavBar component when the tab is clicked.

    Component with Navbar Fixes:

    return (
      <div>
        <NavBar
          items={[
            { label: 'Home', component: <Home />, onClick: () => handleTabClick('Home') },
            { label: 'Profile', component: <ProfileComponent />, onClick: () => handleTabClick('Profile') }
          ]}
        />
      </div>
    );
    

    Navbar Fixes:

    import React from 'react';
    import { useState } from 'react';
    
    const NavBar = ({ items }) => {
      const [activeTab, setActiveTab] = useState(null);
    
      const handleTabClick = (label) => {
        setActiveTab(label);
      };
    
      return (
        <nav className="border-b mb-4">
          <ul className="flex space-x-6 p-4">
            {items.map((item, index) => (
              <NavItem key={index} label={item.label} onClick={item.onClick} isActive={activeTab === item.label}>
                {item.label}
              </NavItem>
            ))}
          </ul>
          {items.map((item) => (
            <div key={item.label}>{activeTab === item.label && item.component}</div>
          ))}
        </nav>
      );
    };
    
    const NavItem = ({ label, onClick, isActive, children }) => {
      const handleClick = () => {
        onClick();
      };
    
      return (
        <li>
          <a
            href="#"
            className={`text-blue-600 hover:text-blue-800 ${isActive ? 'active' : ''}`}
            onClick={handleClick}
          >
            {label}
          </a>
        </li>
      );
    };
    
    export default NavBar;
    
    

    In this updated code, the activeTab state in the NavBar component keeps track of the currently active tab.

    When a tab is clicked, the onClick function for that tab is called, which updates the activeTab state. The NavItem component now receives an isActive prop to determine if it should apply the active styles.

    Additionally, the component prop is used to render the corresponding component for the active tab.

    Login or Signup to reply.
  2. It could be that the nested elements inside your <NavItem> tag (the {item.label}) are taking precedence as the children of your component, after all, nested JSX is passed as the children prop. That would explain why the children prop takes the value of the label. You might want to pass the label as a prop instead of nesting it.

    Also, if what you want is to navigate through your app’s components (pages) programmatically, I suggest you use react-router-dom

    Login or Signup to reply.
  3. you dont use the onClick on the items array, just use the href. You need to set up react-router-dom

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search