How to fetch data of a specific button component through onClick and display the data inside a page in React?

Viewed 51

Issue: I am trying to fetch the data from a specific button component through onClick but it seems that I am quite confused on how to exactly do it. The button component which was rendered should have the functionality of displaying its specific data on a page when the user clicks on it.

Goal: If a specific menu item button(consisting the menu name, price, and number of available) is clicked, then it should display its menu name, price, and number of available inside the current page or ideally, it can also display on a different page.

My source code:

import * as React from "react";
import { useState } from "react";

import { Stack } from "@mui/material";
import ButtonCategoryStyle from "./ButtonCategoryStyle";

import BBQButtons from "./categoryButtons/BBQButtons";
import BilaoButtons from "./categoryButtons/BilaoButtons";
import ChickenButtons from "./categoryButtons/ChickenButtons";

export default function HomeOrderPage() {
  const categories = ["BBQ", "Bilao", "Chicken"];

  const [myCategory, setMyCategory] = useState("");

  return (
    <div>
      {/* RENDERS THE MENU ITEM BUTTONS: */}
      <Stack spacing={0} direction="row">
        {categories.map((category) => (
          <ButtonCategoryStyle
            title={category.toLocaleUpperCase()}
            key={category}
            onClick={() => setMyCategory(category)}
          />
        ))}
      </Stack>

      <div>
        <p>
          {myCategory === "BBQ" && <BBQButtons />}
          {myCategory === "Bilao" && <BilaoButtons />}
          {myCategory === "Chicken" && <ChickenButtons />}
        </p>
      </div>
    </div>
  );
}

Specific button component (BBQ):

import * as React from "react";
import { Stack } from "@mui/material";
import { Button } from "@mui/material";
import Typography from "@mui/material/Typography";

import ButtonCategoryStyle from "../ButtonCategoryStyle";
import ItemsCategoryButton from "../ItemsCategoryButton";

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

export default function BBQButtons() {
  return (
    <React.Fragment>
      <Stack spacing={0} direction="row" sx={{ mb: 4.5 }}>
        <ItemsCategoryButton
          title="Hito (Small)"
          price="120.00"
          availables="20"
         -- onClick here????? --
        />
        <ItemsCategoryButton
          title="Hito (Medium)"
          price="160.00"
          availables="20"
        />
        <ItemsCategoryButton
          title="Hito (Large)"
          price="210.00"
          availables="20"
        />
        <ItemsCategoryButton
          title="Chicken Paa"
          price="75.00"
          availables="20"
        />

        <ItemsCategoryButton
          title="Chicken Pecho"
          price="85.00"
          availables="20"
        />
      </Stack>

      <Stack spacing={0} direction="row" sx={{ mb: 4.5 }}>
        <ItemsCategoryButton
          title="Chicken Baticulon"
          price="15.00"
          availables="20"
        />
        <ItemsCategoryButton
          title="Chicken Isaw (5 sticks)"
          price="25.00"
          availables="20"
        />
        <ItemsCategoryButton
          title="Chicken Atay"
          price="15.00"
          availables="20"
        />
        <ItemsCategoryButton
          title="Pork Tocino"
          price="10.00"
          availables="20"
        />

        <ItemsCategoryButton
          title="Pork Maskara"
          price="25.00"
          availables="20"
        />
      </Stack>

      <Stack spacing={0} direction="row" sx={{ mb: 4.5 }}>
        <ItemsCategoryButton
          title="Pork Belly"
          price="140.00"
          availables="20"
        />
        <ItemsCategoryButton
          title="Hotdog (Beefies)"
          price="15.00"
          availables="20"
        />
      </Stack>
    </React.Fragment>
  );
}

Full source code in Codesandbox: https://codesandbox.io/s/vibrant-germain-76p1er?file=/src/HomeOrderPage.jsx:0-1069

(Either BBQ, BILAO, or CHICKEN button should be clicked first in order to display the menu items.)

Goal appearance: GOAL APPEARANCE

Old StackOverflow questions I read which still confuses me:

Should I use Axios for this even though I don't have an API yet? I only have local data which are directly defined by me.

Currently, I am confused on where to begin using an onClick event, props, hooks for this one. Thus it would be great to get some helpful guides and tips for this functionality that I am working on.

It would indeed help me a lot as I am exploring React at the moment, thank you very much!!!

1 Answers

Most likely you want the data to be dynamic and not hard coded. You should store your items like this

const items = [
  {
    title: "Buffalo Wings",
    price: "200.00",
    availables: "20"
  },
  {
    title: "Battered Chicken (Half)",
    price: "195.00",
    availables: "20"
  },
  {
    title: "Battered Chicken (Whole)",
    price: "380.00",
    availables: "20"
  },
  {
    title: "Garlic Chicken (Half)",
    price: "210.00",
    availables: "20"
  },
  {
    title: "Garlic Chicken (Whole)",
    price: "400.00",
    availables: "20"
  }
];

Then you can map over items to generate the buttons

 <Stack spacing={0} direction="row">
        {items.map((item) => (
          <ItemsCategoryButton
            onClick={() => onSelected(item)}
            key={item.title}
            {...item}
          />
        ))}
      </Stack>

You can keep trace on the selected food on the parent and pass down the setter function to the categories

import * as React from "react";
import { useState } from "react";

import { Stack } from "@mui/material";
import ButtonCategoryStyle from "./ButtonCategoryStyle";

import BBQButtons from "./categoryButtons/BBQButtons";
import BilaoButtons from "./categoryButtons/BilaoButtons";
import ChickenButtons from "./categoryButtons/ChickenButtons";
const categories = ["BBQ", "Bilao", "Chicken"];

export default function HomeOrderPage() {
  const [myCategory, setMyCategory] = useState("");
  const [food, setFood] = useState(null);

  return (
    <div>
      <Stack spacing={0} direction="row">
        {categories.map((category) => (
          <ButtonCategoryStyle
            title={category.toLocaleUpperCase()}
            key={category}
            onClick={() => setMyCategory(category)}
          />
        ))}
      </Stack>

      <div>
        <p>
          {myCategory === "BBQ" && <BBQButtons />}
          {myCategory === "Bilao" && <BilaoButtons />}
          {myCategory === "Chicken" && <ChickenButtons onSelected={setFood} />}
        </p>
      </div>
      {food && food.title}
    </div>
  );
}

The final step is to also pass the onClick function to your custom button component

export default function ButtonCategoryStyle({ title, onClick }) {
  return (
    <Button
      variant="outlined"
      onClick={onClick}
      sx={{
        "&.Mui-selected": {},
        "&.Mui-focusVisible": {
          border: "5px solid #F2A42A"
        },
        ":focus": {
          border: "5px solid #F2A42A"
        },
        ":hover": {
          border: "5px solid #F2A42A",
          backgroundColor: "#green"
        },
        mt: 1,
        ml: 1,
        mb: 8,
        width: 131,
        textTransform: "none",
        backgroundColor: "#1F1D2B",
        borderColor: "#252836",
        borderRadius: 3,
        color: "white",
        height: 49,
        fontFamily: "Barlow Condensed",
        fontSize: "19px"
      }}
    >
      {title}
    </Button>
  );
}

You can them repeat the same process for other categories, note that those categories could contains the items directly.

const categories = [{name: "BBQ", items : []}, {name: "BILAO", items : []}];

codesandbox updated

Related