Home > Back-end >  How to display the content of a specific button after one of three buttons is clicked? All buttons s
How to display the content of a specific button after one of three buttons is clicked? All buttons s

Time:09-10

Goal: I should display the specific contents of a specific button after one of three buttons was clicked. Then, after the specific button is clicked, all three buttons should be hidden and replaced with the contents of the clicked specific button.

Issue: I tried passing props and using if-else statement in terms of conditional rendering but I am having trouble figuring out how to properly state a condition for the functionality to work since the remaining if else statements are ignored. Only the Beef button is working but the rest of the buttons are not.

Source code:

import * as React from "react";
import { Stack } from '@mui/material';
import FoodTraysItemButton from "./FoodTraysItemButton";
import PastaNoodlesButtonsFT from "./foodTraysPages/PastaNoodlesButtonsFT";
import DessertsButtonsFT from "./foodTraysPages/DessertsButtonsFT";
import BeefButtonsFT from "./foodTraysPages/BeefButtonsFT";
import { useState } from "react";

function preventDefault(event) {
  event.preventDefault();
}

export default function FoodTraysButtons(props) {
  const [myBoolBeef, setmyBoolBeef] = useState(true);
  const [myBoolDesserts, setmyBoolDesserts] = useState(true);
  const [myBoolPastaNoodles, setmyBoolPastaNoodles] = useState(true);
  
   function toggleBoolBeef() {
     setmyBoolBeef(!myBoolBeef);
   }

    function toggleBoolDesserts() {
      setmyBoolDesserts(!myBoolDesserts);
    } 

    function toggleBoolPastaNoodles() {
      setmyBoolPastaNoodles(!myBoolPastaNoodles);
    }

  return (
    // stuck here:   (I plan to use multiple separate if else statements to work the functionality out but it doesn't work)
    <React.Fragment> 
     {(() => {
         // only works here
        if (myBoolBeef) {
          return (<Landing toggleBoolBeef={toggleBoolBeef} />);
        } else{
          return <BeefFT/>;
        }
      
// these are ignored:
        if (myBoolDesserts) {
          return (<Landing toggleBoolDesserts={toggleBoolDesserts} />);
        } else{
          return <DessertsFT/>;
        } 

        if (myBoolPastaNoodles) {
          return (<Landing toggleBoolPastaNoodles={toggleBoolPastaNoodles} />);
        } else{
          return <PastaNoodlesFT/>;
        } 


      })()}
    </React.Fragment>
  );

}

function Landing(props) {
  return (
    <div>
      <Stack spacing={0} direction="row" sx={{ mb: 4.5 }}>
        <FoodTraysItemButton
          title="Beef"
          onClick={props.toggleBoolBeef}
        />
      
        <FoodTraysItemButton
          title="Desserts"
          onClick={props.toggleBoolDesserts}
        />
        <FoodTraysItemButton title="Pasta/Noodles" onClick={props.toggleBoolPastaNoodles} />
      
      </Stack>
     

    </div>
  );
}

function BeefFT() {
  return (
    <div>
      <BeefButtonsFT />
    </div>
  );
}


function DessertsFT() {
  return (
    <div>
      <DessertsButtonsFT />
    </div>
  );
}

function PastaNoodlesFT() {
  return (
    <div>
      <PastaNoodlesButtonsFT />
    </div>
  );
}

Full source codes in Codesandbox: beefff

beef

Desserts button: deessers

desserts

Pasta Noodles button: pasta

pastaaaa

In what way should I implement this in order to achieve its functionality?

Your responses would be highly appreciated as I am exploring MUI and React at the moment. It would be a really big help for my project. Thank you very much!!!

CodePudding user response:

Update FoodTraysButtons to hold a single state, selection that is then used to conditionally render the Landing component or any of BeefFT, DessertsFT, or PastaNoodlesFT component.

export default function FoodTraysButtons(props) {
  const [selection, setSelection] = useState();

  const selectHandler = (selection) => setSelection(selection);

  return (
    <React.Fragment>
      {!selection && <Landing onSelect={selectHandler} />}
      {selection === "beef" && <BeefFT />}
      {selection === "dessets" && <DessertsFT />}
      {selection === "pastaNoodles" && <PastaNoodlesFT />}
    </React.Fragment>
  );
}

Update the Landing component to take a single onSelect prop callback.

function Landing({ onSelect }) {
  const selectHandler = (selection) => () => onSelect(selection);
  return (
    <div>
      <Stack spacing={0} direction="row" sx={{ mb: 4.5 }}>
        <FoodTraysItemButton title="Beef" onClick={selectHandler("beef")} />
        <FoodTraysItemButton
          title="Desserts"
          onClick={selectHandler("desserts")}
        />
        <FoodTraysItemButton
          title="Pasta/Noodles"
          onClick={selectHandler("pastaNoodles")}
        />
      </Stack>
    </div>
  );
}

Edit how-to-display-the-content-of-a-specific-button-after-one-of-three-buttons-is-cl

CodePudding user response:

You need a switch case block instead of multiple boolean value state. Consider this way of structuring your code:

const menuState = {
  NONE: "none",
  BEEF: "beef",
  DESSERTS: "desserts",
  PASTA: "pasta"
};

export default function FoodTraysButtons(props) {
  const [selectedMenu, setSelectedMenu] = useState(menuState.NONE);

  const renderMenu = () => {
    switch (selectedMenu) {
      case menuState.BEEF:
        return <BeefFT />;
      case menuState.DESSERTS:
        return <DessertsFT />;
      case menuState.PASTA:
        return <PastaNoodlesFT />;
      case menuState.NONE:
      default:
        return null;
    }
  };

  return (
    <React.Fragment>
      {selectedMenu === menuState.NONE && (
        <Landing setSelectedMenu={setSelectedMenu} />
      )}
      {renderMenu()}
    </React.Fragment>
  );
}

function Landing(props) {
  return (
    <div>
      <Stack spacing={0} direction="row" sx={{ mb: 4.5 }}>
        <FoodTraysItemButton
          title="Beef"
          onClick={() => props.setSelectedMenu(menuState.BEEF)}
        />

        <FoodTraysItemButton
          title="Desserts"
          onClick={() => props.setSelectedMenu(menuState.DESSERTS)}
        />
        <FoodTraysItemButton
          title="Pasta/Noodles"
          onClick={() => props.setSelectedMenu(menuState.PASTA)}
        />
      </Stack>
    </div>
  );
}

Working Demo:

Edit show-hide-buttons-ralph (forked)

NOTE: If you want to always show the button menu then remove the selectedMenu === menuState.NONE wrapper condition.

  • Related