Home > other >  Need loop to simplify a component
Need loop to simplify a component

Time:08-14

I am building a Tabs component in React JS. I want to create a loop for my code, instead of hardcoding every tab(title, content). The code is working I need to simplify the code with a loop.

Tabs Component

import { useState } from "react"
import "./TabsStyles.css"

const Tabs = () => {

    const [toggleTabsNumber, setToggleTabsNumber] = useState(null)

    const togglerFunction = (index) => {
        setToggleTabsNumber(index)
    }

  return (
    <div>
        <div className="c-tabs-main-container">
            <div className="c-tabs-title-container">
                <h3 onClick={() => togglerFunction(1)}>Tab 01</h3>
                <h3 onClick={() => togglerFunction(2)}>Tab 02</h3>
                <h3 onClick={() => togglerFunction(3)}>Tab 03</h3>
            </div>

            <div className="c-tabs-content-container">
                <p className={toggleTabsNumber === 1 ? "c-active"  : ""}>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ut similique asperiores nihil ullam non ad, dolorem quam eligendi rem praesentium nemo sed error pariatur voluptates hic voluptatem aliquam sapiente unde?</p>
                <p className={toggleTabsNumber === 2 ? "c-active"  : ""}>Qquam eligendi rem praesentium nemo sed error pariatur voluptates hic voluptatem aliquam sapiente unde?</p>
                <p className={toggleTabsNumber === 3 ? "c-active"  : ""}>PPhic voluptatem aliquam sapiente unde?</p>
            </div>
        </div>        
    </div>
  )
}

export default Tabs

CodePudding user response:

You can modify Tabs Function component by passing tabs items as props; Then, loop them in your jsx.

const Tabs = ({ tabs }) => {
  const [toggleTabsNumber, setToggleTabsNumber] = useState(null);

  const togglerFunction = (index) => {
    setToggleTabsNumber(index);
  };

  const isActiveTab = useCallback(
    (tabId) => {
      return toggleTabsNumber === tabId;
    },
    [toggleTabsNumber]
  );

  return (
    <div className="c-tabs-main-container">
      <div className="c-tabs-title-container">
        {tabs.map((tab, indx) => (
          <h3
            key={`tab-title-${indx}-${tab.title}`}
            onClick={() => {
              togglerFunction(tab.id);

              tab?.onClick?.();
            }}
          >
            {tab.title}
          </h3>
        ))}
      </div>

      <div className="c-tabs-content-container">
        {tabs.map((tab, indx) => (
          <p key={`tab-content-${indx}-${tab.content}`} className={isActiveTab(tab.id) ? 'c-active' : ''}>
            {tab.content}
          </p>
        ))}
      </div>
    </div>
  );
};
tabs 

is going to be array of tab which is something like

    interface Tab {
      id: string;
      title: string;
      content: string;
      onClick?: function;
    }

CodePudding user response:

How about something like this as a quick draft

import { useState } from "react"
import "./TabsStyles.css"

export const Tabs = (props) => {

  const [activeTab, setActiveTab] = useState(0);

  const tabs = React.Children.toArray(props.children)
    .filter(child => React.isValidElement(child) && child.type === Tab);

  return (
    <div>
      <div className="c-tabs-main-container">
        <div className="c-tabs-title-container">
          {
            tabs.map((tab, index) => <h3 key={tab.key ?? index} onClick={() => setActiveTab(index)}>{
              tab.title
            }</h3>)
          }
        </div>

        <div className="c-tabs-content-container">
          {
            tabs.map((tab, index) => <div key={tab.key ?? index} className={activeTab === index ? "c-active" : ""}>{
              tab.children
            }</div>)
          }
        </div>
      </div>
    </div>
  )
}

// a vessel to collect the title and tab content as JSX and a marker to determine <Tab />s from possible garbage.
export const Tab = (props) => null;

which would then be used like this:

<Tabs>
  <div> this will be ignored; only Tabs are rendered.</div>

  <Tab title="Tab 01">
    Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ut similique asperiores nihil ullam non ad, dolorem quam eligendi rem praesentium nemo sed error pariatur voluptates hic voluptatem aliquam sapiente unde?
  </Tab>

  <Tab title="Tab 02">
    Qquam eligendi rem praesentium nemo sed error pariatur voluptates hic voluptatem aliquam sapiente unde?
  </Tab>

  <Tab title="Tab 03">
    PPhic voluptatem aliquam sapiente unde?
  </Tab>
</Tabs>

this code may contain errors, I didn't test it, just typed it down quickly.

  • Related