6

I'm conditionally rendering some components, but I would like to know if there is a more efficient way (for exemple, with switch case):

     export const Culture = () => {
      const { query } = useRouter();
      const currentSection = query.section || "";
      return (
        <div className="content">
          <Navigation
            className={currentSection !== "" ? "sub_nav" : "sub_nav active_menu"}
            category="culture"
          />
          {currentSection === "" && <CultureCulture category="cultureCulture" />}
          {currentSection === "elephant" && (
            <CultureCulture category="cultureElephant" />
          )}
          {(currentSection === "espace-musee" ||
            currentSection === "quebecor-gallery") && (
            <CultureCulture category="cultureGallery" />
          )}
          {currentSection === "culture-d-ici" && (
            <CultureCulture category="cultureIci" />
          )}
          {(currentSection === "bilan-culturel" ||
            currentSection === "culture-report") && (
            <CultureCulture category="cultureReport" />
          )}
        </div>
      );
    };
    export default Culture;
Amila Senadheera
  • 12,229
  • 15
  • 27
  • 43
analuspi
  • 184
  • 1
  • 1
  • 10
  • 1
    Does this answer your question? [How to use switch statement inside a React component?](https://stackoverflow.com/questions/46592833/how-to-use-switch-statement-inside-a-react-component) – Tushar Shahi Jan 19 '22 at 15:46

5 Answers5

11

You can actually use switch-case blocks in a separate function to render them.

export const Culture = () => {
    const { query } = useRouter();
    const currentSection = query.section || "";

    const renderCurrentSelection = () => {
        switch (currentSection) {
            case "":
                return <CultureCulture category="cultureCulture" />;
            case "elephant":
                return <CultureCulture category="cultureElephant" />;
            case "espace-musee":
            case "quebecor-gallery":
                return <CultureCulture category="cultureGallery" />;
            case "culture-d-ici":
                return <CultureCulture category="cultureIci" />;
            case "bilan-culturel":
            case "culture-report":
                return <CultureCulture category="cultureReport" />;
            default:
                return null;
        }
    };

    return (
        <div className="content">
            <Navigation
                className={
                    currentSection !== "" ? "sub_nav" : "sub_nav active_menu"
                }
                category="culture"
            />
            {renderCurrentSelection()}
        </div>
    );
};
export default Culture;
Amila Senadheera
  • 12,229
  • 15
  • 27
  • 43
2

You can create an object which consist of key , value related to your category, and instead of creating some conditional render, just reading the culture from the object, like this:

const categories = { 
  'default': 'cultureCulture',
  'elephant':'cultureElephant', 
  'espace-musee': 'cultureGallery',
  'quebecor-gallery': 'cultureGallery',
  'culture-d-ici': 'cultureIci',
  'bilan-culturel': 'cultureReport', 
  'culture-report': 'cultureReport',
}

and use it in your component like this:

export const Culture = () => {
  const { query } = useRouter();
  const currentSection = query.section || 'default';
  return (
    <div className="content">
      <Navigation
        className={currentSection !== "" ? "sub_nav" : "sub_nav active_menu"}
        category="culture"
      />
      <CultureCulture category={categories[currentSection]} />
    </div>
  );
};
Saeed Shamloo
  • 6,199
  • 1
  • 7
  • 18
1

Assuming the "efficient" word refers to letter count, then:

export const Culture = () => {
  const { query } = useRouter();
  const currentSection = query.section || "";
  
  let navClass = "sub_nav";
  if (currentSection == "") {
    navClass = "sub_nav active_menu";
  }
  
  let category = "";
  switch (currentSection) {
    case "elephant":
      category = "cultureElephant";
      break;
    case "espace-musee":
    case "quebecor-gallery":
      category = "cultureGallery";
      break;
    case "culture-d-ici":
      category = "cultureIci";
      break;
    case "bilan-culturel":
    case "culture-report":
      category = "cultureReport";
      break;
    default:
      category = "cultureCulture";
      break;
  }
  
  return (
    <div className="content">
      <Navigation
        className={navClass}
        category="culture"
      />
      <CultureCulture category={category} />
    </div>
  );
};
export default Culture;

It saves 43 letters + more readable because logic and markup are not too blended.

Thor-x86_128
  • 157
  • 18
0

You can have an object with all the keys that are mapped to the right category value. Like:

const MAPPED_CATEGORIES = {
  elephant: 'cultureElephant',
  'espace-musee': 'cultureGallery',
  'quebecor-gallery': 'cultureGallery',
  'bilan-culturel': 'cultureIci',
  'culture-report': 'cultureReport'
}

And then you can get the right category by:

<CultureCulture
  category={(currentSection && MAPPED_CATEGORIES[currentSection]) || 'cultureCulture'}
/>
giankotarola
  • 765
  • 7
  • 13
0

Create a function to get the category based on current section:

function getCategory(currentSection = "") {
  switch(currentSection) {
    case "elephant":
      return "cultureElephant"
    case "espace-musee":
    case "quebecor-gallery":
      return "cultureGallery"
    case "culture-d-ici":
      return "cultureIci"
    case "bilan-culturel":
    case "culture-report":
      return "cultureReport"
    default:
      return "cultureCulture"
  }
}

export const Culture = () => {
  const { query } = useRouter();
  const currentSection = query.section || "";
  return (
    <div className="content">
      <Navigation
        className={currentSection !== "" ? "sub_nav" : "sub_nav active_menu"}
        category="culture"
      />
        <CultureCulture category={getCategory(currentSection)} />
    </div>
  );
};
export default Culture;