简体   繁体   中英

Using onClick event in React map function

I am trying to loop over nested object in using map on List Component from MUI. When performing click all elements are getting clicked.

This is my class component:

class TablePivot extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            pivotData: [],
            firstLevelOpen: false,
            secondLevelOpen: false,
            thirdLevelOpen: false,
        }
    handleFirstListClick = () =>{
        this.setState({firstLevelOpen:!this.firstLevelOpen})
        console.log(this.secondLevelOpen)
    }

    handleSecondListClick = () =>{
        this.setState({secondLevelOpen:!this.secondLevelOpen})
        console.log(this.secondLevelOpen)
    }
    
    handleThirdListClick = () =>{
        this.setState({thirdLevelOpen:!this.thirdLevelOpen})
        console.log(this.thirdLevelOpen)
    }

    render () {
        
        return (
            <>
                
                <List>
                    {Object.entries(this.state.pivotData).map((key, val) =>{
                        // console.log(key[1])
                        return (
                        <ListItemButton onClick = {event => this.handleFirstListClick}>
                            <ListItemText primary={key[0]} />
                            {this.state.firstLevelOpen ? <ExpandLess /> : <ExpandMore />}
                            {Object.entries(key[1]).map((key,index) =>{
                                return (
                                    <Collapse in={this.state.firstLevelOpen} timeout="auto" unmountOnExit>
                                        <List component="div" disablePadding>
                                        <ListItemButton onClick = {this.handleSecondListClick} sx={{ pl: 4 }}>
                                            <ListItemText primary={key[0]} />
                                            {this.state.secondLevelOpen ? <ExpandLess /> : <ExpandMore />}
                                            {Object.entries(key[1]).map((key,index) =>{
                                                    <Collapse in={this.state.secondLevelOpen} timeout="auto" unmountOnExit>
                                                        <List component="div" disablePadding>
                                                        <ListItemButton onClick = {this.handleThirdListClick} sx={{ pl: 4 }}>
                                                            <ListItemText primary={key[1]} />
                                                            {this.state.thirdLevelOpen ? <ExpandLess /> : <ExpandMore />}
                                                            {/* {
                                                                Object.entries(key[1]).map((key,index) =>{
                                                                    return (console.log[key])
                                                                })
                                                            } */}
                                                        </ListItemButton>
                                                        </List>
                                                    </Collapse>
                                                })
                                            }
                                        </ListItemButton>
                                        </List>
                                    </Collapse>
                                    
                                )
                            })}
                        </ListItemButton>
                    )
                    
                    
                    })}
                </List>

                
                
                <Snackbar anchorOrigin={{ vertical : "top", horizontal : "right" }} open={this.state.alert} autoHideDuration={5000} onClose={() => this.setState({alert : false})}>
                    <Alert variant="filled" elevation={6} onClose={() => this.setState({alert : false})} severity={this.state.severity}>
                        {this.state.alertMsg}
                    </Alert>
                </Snackbar>
            </>
        )
    }

I have tried passing index and event inside onclick like this:

handleFirstListClick(event, index) {
        console.log(event.target)

        this.setState(
            prevState => ({
                ...prevState.firstLevelOpen,
                [index]: !prevState.firstLevelOpen
            })
        )

        console.log(this.state.firstLevelOpen)


        // if (this.state.firstLevel === true)
        //     firstLevel[index] = false
        // else
        //     firstLevel[index] = true

        // this.setState({firstLevelOpen:firstLevel});

    }

// Changes inside render() inside list component for passing value
<ListItemButton onClick = {event => this.handleFirstListClick(event, val)}>

But doing this will not update state properly. I am not understanding what is going wrong. I am learning react using project. I am struggling for this click event a lot.

When you click the first ListItemButton , it set the firstLevelOpen state to true .

And at this part of the code {this.state.firstLevelOpen? <ExpandLess />: <ExpandMore />} {this.state.firstLevelOpen? <ExpandLess />: <ExpandMore />} because the firstLevelOpen is now true , all the first level ExpandLess component will be visible.

To handle the state for each button in the list, you can change the state from boolean into object. What you already did is very similar to the code below.

this.state = {
    pivotData: [],
    firstLevelOpen: {},
    secondLevelOpen: {},
    thirdLevelOpen: {},
}

and on the click handler

handleFirstListClick(event, index) {
    this.setState(
        prevState => ({
            firstLevelOpen: {
                ...prevState.firstLevelOpen,
                [index]: !prevState.firstLevelOpen[index]
            }
        })
    )
}

I haven't test it yet, but I guess it should work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM