简体   繁体   English

在 React 中使用 onClick 事件 map function

[英]Using onClick event in React map function

I am trying to loop over nested object in using map on List Component from MUI.我正在尝试在 MUI 的列表组件上使用 map 循环嵌套的 object。 When performing click all elements are getting clicked.执行单击时,所有元素都被单击。

This is my class component:这是我的 class 组件:

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:我试过在 onclick 中传递索引和事件,如下所示:

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.但这样做不会正确更新 state。 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 .当您单击第一个ListItemButton时,它将firstLevelOpen state 设置为true

And at this part of the code {this.state.firstLevelOpen? <ExpandLess />: <ExpandMore />}在这部分代码{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. {this.state.firstLevelOpen? <ExpandLess />: <ExpandMore />}因为firstLevelOpen现在为true ,所有第一级ExpandLess组件都将可见。

To handle the state for each button in the list, you can change the state from boolean into object.要处理列表中每个按钮的 state,您可以将 state 从 boolean 更改为 ZA8CFDE63131BD59EB2AC9ZC966F 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.我还没有测试它,但我想它应该可以工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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