Display the initial MUI components from an array of data in a distinctive manner

Trying to display the content of an Accordion by passing props down through a list array to a component. I have identified the issue but unsure how to call the component and pass the props differently. Below is the code snippet.

Code for the parent component

const Sandbox = () => {

let summaryContents: any[] = [
    {
      Title: "Construction costs",
      TotalPrice: "$25000",
      Subcontents: [
        {
          Subtitle: "Sanitation",
          SubtitlePrice: "$5000",
        },
        {
          Subtitle: "PoolLights",
          SubtitlePrice: "$5000",
        },
        {
          Subtitle: "PoolCleaner",
          SubtitlePrice: "$15000",
        },
      ],
    },
    {
      Title: "Pool interior costs",
      TotalPrice: "$20000",
      Subcontents: [
        {
          Subtitle: "Title1",
          SubtitlePrice: "$5000",
        },
        {
          Subtitle: "Title2",
          SubtitlePrice: "$10000",
        },
        {
          Subtitle: "Title3",
          SubtitlePrice: "$5000",
        },
      ],
    },
];


  let summaryContentsList: any[] = [];

  summaryContents.forEach((item: any, index: number) => {
    summaryContentsList.push(
      <QuoteSummary
        
        Title={item.Title}
        TotalPrice={item.TotalPrice}
        Subtitle={item.Subcontents.Subtitle}
        SubtitlePrice={item.Subcontents.SubtitlePrice}
      />
    );
  });
  return (
    <>
      
      {summaryContentsList}
    </>
  );
};

Component code for the child component

const QuoteSummary: FC<QuoteSummaryProps> = (props: QuoteSummaryProps) => {
  const classes = useStyles();
  return (
    <QuoteCard>
      <Typography variant="h1" sx={{ paddingBottom: 2 }}>
        Quote Summary
      </Typography>
      <DialogCloseButton onClose={clicked} />

      <Accordion
        className={classes.accordion}
        sx={{
          paddingTop: 0,
        }}
      >
        <AccordionSummary
          expandIcon={<ExpandMoreIcon />}
          aria-controls="panel1a-content"
          id="panel1a-header"
        >
          <Typography variant="h3">{props.Title}</Typography>
          <Typography variant="h3" sx={{ paddingLeft: 10 }}>
            {props.TotalPrice}
          </Typography>
        </AccordionSummary>
        <AccordionDetails>
          <Typography>{props.Subtitle}</Typography>
          <Typography>{props.SubtitlePrice}</Typography>
        </AccordionDetails>
      </Accordion>
    </QuoteCard>
  );
};

https://i.stack.imgur.com/0zrN8.png

The current display shows the Title repeated multiple times within each accordion. The desired outcome is to render the Title once with its corresponding accordion contents below. What approach should be taken to achieve this?

Answer №1

To optimize your code, consider moving the QuoteCard component outside and only including the Accordion item inside the child component:

const QuoteSummary: FC<QuoteSummaryProps> = (props: QuoteSummaryProps) => {
  return (
    <Accordion>
      {...}
    </Accordion>
  );
};
<QuoteCard>
  <Typography variant="h6" sx={{ paddingBottom: 2 }}>
    Quote Summary
  </Typography>
  <DialogCloseButton onClose={() => {}} />

  {summaryContents.map((item) => (
    <QuoteSummary
      Title={item.Title}
      TotalPrice={item.TotalPrice}
      Subtitle={item.Subcontents.Subtitle}
      SubtitlePrice={item.Subcontents.SubtitlePrice}
    />
  ))}
</QuoteCard>

UPDATE: Another suggestion is to dynamically render the title in the child component based on the props passed down from the parent:

const QuoteSummary: FC<QuoteSummaryProps> = (props: QuoteSummaryProps) => {
  return (
    <QuoteCard>
      {props.displayTitle && (
        <Typography variant="h6" sx={{ paddingBottom: 2 }}>
          Quote Summary
        </Typography>
      )}
      <DialogCloseButton onClose={() => {}} />
      <Accordion>
        {...}
      </Accordion>
    </QuoteCard>
  );
};
<>
  {summaryContents.map((item, i) => (
    <QuoteSummary
      displayTitle={i === 0}
      Title={item.Title}
      TotalPrice={item.TotalPrice}
      Subtitle={item.Subcontents.Subtitle}
      SubtitlePrice={item.Subcontents.SubtitlePrice}
    />
  ))}
</>

https://codesandbox.io/s/69654195-avoid-few-elements-of-a-component-in-react-when-rendering-mui-accordion-through-mm975?file=/demo.tsx

Answer №2

If you want to display array items using a render function, you can do it like this:

const DisplayItems = () => {
  const itemArray: any[] = [
    {
      Name: "Item1",
      Price: "$10",
    },
    {
      Name: "Item2",
      Price: "$20",
    },
    {
      Name: "Item3",
      Price: "$30",
    },
  ];

  const renderItem = (item: any) => (
     <Item
        Name={item.Name}
        Price={item.Price}
      />
  );

  return (
    <>
      {itemArray.map(renderItem)}
    </>
  );
};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for resolving the "Page Not Found" error in your NextJs application

I am organizing my files in the following structure src/ ├── app/ │ ├── pages/ │ │ ├── authentication/ │ │ │ ├── SignUp/ │ │ │ │ └── page.tsx │ │ │ └── SignIn/ │ ...

React Error: The module 'common' could not be located

I've been searching high and low on the web for a solution to this problem, but so far, nothing I've found has done the trick. I'm fairly new to React, but a friend of mine requested my assistance with some CSS work on his React project, so ...

Creating a different type by utilizing an existing type for re-use

Can you help me specify that type B in the code sample below should comprise of elements from interface A? The key "id" is mandatory, while both "key" and "value" are optional. interface A { id: string; key: string; value: string | number; } /** ...

the <MapView/> component in react-native-maps cannot be displayed

I am attempting to display a native map using the coordinates from the example but encountering an error: *note using iOS and a real device for debugging ERROR: Could not inset compass from edges 9 Could not inset scale from edge Could not inset legal ...

Arrange the row information in the MUI DataGrid in order to prepare it for exporting to CSV or Excel

Is there a way to organize row data for exporting to CSV or Excel with the MUI DataGrid? Take a look at my code snippet for the toolbar. slots={{ noRowsOverlay: NoDataComponent, noResultsOverlay: NoDataComponent, toolbar: ( ...

What is the best way to create a dynamic sitemap in Next.js version 14?

I've encountered an issue with the code snippet I'm using for a dynamic sitemap on my blog post website built with Next.js 14. While it works perfectly fine in development, it fails to generate a dynamic sitemap in the build or production environ ...

Customizing Material UI InputProps with HTML attributes: A step-by-step guide

When using react-number-format with Material UI Textfield, I'm attempting to set a maximum value of 100 for my field. Numbers above 100 should not be allowed. How can this be achieved using the HTML attribute: min? import InputAdornment from "@ma ...

What is the best way to distribute components with varying cell heights?

I am currently working on creating a user interface layout with components that need to be arranged in a specific order, as depicted in the accompanying image. My task involves developing a Material UI Dialog within a React application based on the design ...

Encountering an issue while setting up a Next.js project, I am struggling to find a solution despite trying various methods

I attempted to install Next.js, and even updated my npm version in order to create a new React project with the latest Next.js. However, I kept encountering the same error. Aborting installation. Unexpected error. Please report it as a bug: Error: spawn ...

Manipulate classes by adding or removing them on click events in Angular

I am struggling to implement the angular ngClass for adding a class with a click event. Despite calling a function that should change the value of the "isExpandedConectivity" variable when clicking on the "li" element, it doesn't seem to work as expec ...

Error in NextJs: The text content does not align with the server-rendered content

I am working on a new project using "NextJs", "date-fns", and "React-Calendar". However, I am facing an issue with date rendering between the server side (nodejs =english format) and client side (french): Warning: Text content did not match. Server: "April ...

developed a website utilizing ASP MVC in combination with Angular 2 framework

When it comes to developing the front end, I prefer using Angular 2. For the back end, I stick with Asp MVC (not ASP CORE)... In a typical Asp MVC application, these are the steps usually taken to publish the app: Begin by right-clicking on the project ...

Verify if the array entries match

Within my select element, I populate options based on an array of values. For example: [{ name: 'A', type: 'a', }, { name: 'B', type: 'b', }, { name: 'B', type: 'b', }, { name: &apos ...

Execute JavaScript function on click event in NextJS

Is it possible to execute a JavaScript function on the client side without using addEventListener? This situation works with addEventListener. MyComponent.js import Script from 'next/script' export default function MyComponent({ props }) { ...

When using React hooks forms, setting default values from a reduced array does not automatically populate the form. However, manually entering the same object into the form does

As I work with react hooks forms, I am facing a challenge in setting default values for a form generated by mapping over an array to output the inputs. After reducing the array into an object format like {name0:"fijs",name1:"3838"...}, manually passing thi ...

Is there a way to prevent the arrow up and down events from functioning on the MUI Menu?

My menu features a text field and a button. The text field is of type number, so ideally when I click on it and use the arrow up and down keys, the value should increase and decrease. However, instead of that functionality, the menu items are being selecte ...

NextJS 13 - displaying a fully loaded page: tips and tricks

Hello there! I am just starting out in the world of NextJS (Frontend) and practicing some new concepts. One question that I have is how to ensure that a page is only displayed once everything has loaded, including all HTTP requests returning responses. Her ...

What is the correct way to utilize drei's useGLTF function?

Despite following the react-three docs and various examples, I am struggling to get drei useGLTF to function properly in my project. I have a basic Next|React|react-three/fiber project that I built from scratch. My goal is to load the astronaut example an ...

Reactjs-ffsevents does not exist as a function

An error occurred: TypeError: fsevents is not a function. This issue is located in the FSEventsWatcher file at line 162. A new FSEventsWatcher was attempted to be created in jest-haste-map, triggering this error. The watcher creation process involved map ...

Implementing inline styles in the HEAD section of a Next.js website

I currently have a blog hosted on Jekyll at , and I'm looking to migrate it to Next.js. My unique approach involves embedding all the styles directly into the HEAD element of each HTML page, without utilizing any external stylesheet files. However, wh ...