Creating a dynamic state management system for multiple Collapse components can be achieved by utilizing

I am trying to create a Collapse menu from array data,

Currently, when I click on any menu all sub menus expand

I believe my issue lies in not being able to set a unique "open" state for each Main menu

I want to avoid assigning a "state" to accommodate potential future data that may have 3 or 4 levels

I am using React.js and material-ui

Please assist me with this problem

Thank you in advance

const myData = [
  {
    id: '1',
    nameHeader: 'Header1',
    subMenu: [{ id: '1', name: 'subMenu1' }, { id: '2', name: 'subMenu2' }]
  },
  {
    id: '2',
    nameHeader: 'Header2',
    subMenu: [{ id: '1', name: 'subMenu1' }, { id: '2', name: 'subMenu2' }]
  }
]

class Myclass extends Component {
  state = { open: false }

  handleClick = () => {
    this.setState(state => ({ open: !state.open }))
  }

  render() {
    const { open } = this.state
    return (
      <div style={{ marginRight: '15px' }}>
        <List component="nav">
          {myData.map(each => (
            <React.Fragment key={each.id}>
              <ListItem button onClick={this.handleClick}>
                <ListItemText inset primary={each.nameHeader} />
                {open ? <ExpandLess /> : <ExpandMore />}
              </ListItem>
              <Divider />
              <Collapse in={open} timeout="auto" unmountOnExit>
                <List component="div" disablePadding>
                  {each.subMenu.map(subData => (
                    <ListItem key={subData.id} button>
                      <ListItemText inset primary={subData.name} />
                    </ListItem>
                  ))}
                </List>
              </Collapse>
            </React.Fragment>
          ))}
        </List>
      </div>
    )
  }
}
export default Myclass

Answer №1

I am facing an issue where I am unable to set a unique state of "open" for the Main menu.

It seems like you have two different sub menus that you want to collapse/expand independently without affecting each other. To achieve this, you need to implement a way to store the current 'open' state for each menu separately.

You already have unique IDs for your menus, so you can use them to reach your objective. One approach is to enhance your state by including specific settings for each menu:

state = { settings: [{ id: "1", open: false }, { id: "2", open: false }] };

This structure will allow you to track the collapsed status of each menu.

To handle this, you should modify your handleClick function to only update the state of the clicked menu item:

handleClick = id => {
  this.setState(state => ({
    ...state,
    settings: state.settings.map(item =>
      item.id === id ? { ...item, open: !item.open } : item
    )
  }));
};

In your render function, ensure that you pass the correct menu item ID to your handleClick function and select the appropriate open state:

<React.Fragment key={each.id}>
  <ListItem button onClick={() => this.handleClick(each.id)}>
    <ListItemText inset primary={each.nameHeader} />
    settings.find(item => item.id === each.id).open
    ? "expanded"
    : "collapsed"}
  </ListItem>
  <Divider />
  <Collapse
    in={settings.find(item => item.id === each.id).open}
    timeout="auto"
    unmountOnExit
  >
  <List component="div" disablePadding>
    {each.subMenu.map(subData => (
      <ListItem key={subData.id} button>
        <ListItemText inset primary={subData.name} />
      </ListItem>
     ))}
   </List>
 </Collapse>
</React.Fragment>

View the solution in action here: https://codesandbox.io/s/6xjz837j9z

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

Execute Function on Double-Click with Flot.js

Is there a way to run a function when the mouse double-clicks while using flot? Currently, I am only able to trap the single click with the following code: $(graph).bind('plotclick', function(event, pos, item) { if (item) { .... ...

"Enhancing User Experience with Bootstrap's masonry layout feature while retaining scroll position

I'm faced with a puzzling situation and I can't seem to find the solution. Currently, I am utilizing Bootstrap 5 along with the masonry layout as recommended here: https://getbootstrap.com/docs/5.0/examples/masonry/, and it is working perfectly. ...

Creating a sliding bottom border effect with CSS when clicked

Is there a way to animate the sliding of the bottom border of a menu item when clicked on? Check out the code below: HTML - <div class="menu"> <div class="menu-item active">menu 1</div> <div class="menu-item">menu 2</ ...

Is the file corrupt using node.js?

Looking for ways to determine if a file is corrupted using node.js? I have attempted various File System methods, such as fs.readFile, fs.open, and fs.access, but all of them are showing an OK status. However, I am confident that my file is corrupted base ...

Can someone guide me on how to retrieve data from a MUI table within a React project

Currently, I am retrieving data from a server in JSON format and looping through this data to display specific information. Everything is functioning as expected, but I'm encountering an issue with a Popover element that contains items with onclick ev ...

Executing a prop function within the useEffect hook: a step-by-step guide

I am attempting to address this warning in a react component Line 19:8: React Hook useEffect has a missing dependency: 'handleChange'. Either include it or remove the dependency array react-hooks/exhaustive-deps This is the component: ...

Exploring the elements within array structures

I'm facing an issue with my API response. I'm trying to filter the links and check if the source and target name properties in each object match a specific string. However, I am having trouble accessing the name property. Any suggestions on how I ...

Using Vuetify to send a parameter from a select option to a method as a parameter

Just starting out with vuejs and encountering an issue passing parameters from a selected option to my JavaScript method. In my updateClientIsMaster method, the item is always undefined. However, when I added v-on:change="updateClientIsMaster in the & ...

React Ag-Grid Material UI Integration

Are there any standout instances of incorporating AgGrid with React Material UI, particularly when it comes to developing custom themes? The examples provided on the AgGrid website focus on css/scss rather than styled components, which are the preferred ...

Tips for effectively splitting arrays nested within an array using JavaScript

Here is an example of slicing an array to generate a new one: var array= [ [1,"dataA","dataB","dataC","dataD"...], [2,"dataA","dataB","dataC","dataD"...], [3,"dataA","dataB","dataC","dataD"...], [4,"dataA","dataB","dataC","dataD"...]... ...

Angular JS is encountering an issue where the promise object is failing to render correctly

I'm currently learning Angular and I have a question about fetching custom errors from a promise object in Angular JS. I can't seem to display the custom error message on my HTML page. What am I missing? Below is my HTML file - <!DOCTYPE htm ...

jquery is unable to fetch the input value from a dynamically generated field inside a function

Something peculiar keeps happening to me when I utilize jQuery, which is different from what others have encountered in the forums. Whenever I make an ajax call and generate an input element (on success), like so: Start Date: <input type="text" id="gr ...

Learn how to invoke a method of a particular subchild in the component hierarchy using React

As I delve into the world of React, a theoretical problem caught my attention. It involves figuring out how to solve a particular issue within a set of components. Let's say we have the following components: class Universe extends React.Component { ...

What steps should I take to resolve the "You do not have authorization to access this directory or page" error in Azure App Services?

Currently, I am attempting to deploy my Next.js 13 application to AppServices using Github Actions. The compilation process on Github was successful, however, I am encountering an issue where my application does not seem to be deploying or starting up prop ...

Failed deployment of a Node.js and Express app with TypeScript on Vercel due to errors

I'm having trouble deploying a Nodejs, Express.js with Typescript app on Vercel. Every time I try, I get an error message saying "404: NOT_FOUND". My index.ts file is located inside my src folder. Can anyone guide me on the correct way to deploy this? ...

When attempting to convert large objects into JSON using JSON.stringify, a RangeError is thrown due to

Trying to convert a massive JavaScript Object into a string using JSON.stringify in my Node.js application. The objects are extremely large (tens of mega bytes) and do not contain any functions. I need to save the serialized objects to a file. However, I a ...

What is the best method for choosing HTML "ids" that are generated automatically by DevExpress controls using JavaScript DOM manipulation?

How can I create a pop-up that displays unique information for each of the hundreds of html divs with a common class but individual ids generated by DevExpress Controls? I have a large number of automatically generated html div "ids" and I'm looking ...

What is the best way to minify and concatenate multiple CSS files only after converting SCSS to CSS with Gulp?

When attempting to convert my scss files to css files using gulp, I encountered an issue. After writing the scss code, it is easily converted to css. However, I wanted to minify this css and save it in a different folder called 'min'. Within the ...

Issue with AngularJS UI Router not loading the inline template and controller

I am trying out UI Router for the first time in my AngularJS project. I am facing an issue where, when I click on a link to view a post, it doesn't display. The post template is not visible and I remain on the home page. The URL flashes as http://loc ...

Is there a way to utilize jQuery for parsing the XML file?

When trying to parse the file, the value for "name" in the code is always an empty string. Here is my XML data: <row> <id>1</id> <AnrufenZahl>64</AnrufenZahl> <NameOperator>Ioan</NameOperator> </row> ...