首页 > 解决方案 > 使用递归渲染的 Material UI 嵌套列表不适用于反应钩子

问题描述

我正在做一个项目,在该项目中,我需要一个带有使用 Material UI 创建的嵌套列表的侧边栏,如果我去演示并复制嵌套列表代码,一切都很好,但它带有很多代码重复。所以经过一番挖掘后,我发现了递归渲染函数的要点因此,经过一番挖掘,我发现了用类编写的我正在使用反应钩子,功能逻辑没有按预期工作。

问题: 我有 3 级导航,父级,然后子级和子级包含更多项目(孙子到父级)。因此,当我单击父项时,所有子项都会出现,但是当我单击任何子项时,整个列表都会关闭。

这是我的代码:

// useState hook with empty object as an initial Value

const [open1, setOpen1] = React.useState({});

// this method sets the current state of a menu item i.e whether it is in expanded or collapsed or a collapsed state

const handleClick = (param) => {
        setOpen1(prevState => ({[param]: !prevState[param]}));
    };

// if the menu item doesn't have any child, this method simply returns a clickable menu item that redirects to any location and if there is no child this method uses recursion to go until the last level of children and then returns the item by the first condition.

function nestedMenu(items) {

        return items.map((nav) => {
            if (!nav.children) {
                return (
                    <div key={nav.id}>
                        <ListItem button>
                            <ListItemText primary={nav.name} />
                        </ListItem>
                    </div>
                )
            }
            return (
                <div key={nav.id}>
                    <ListItem button onClick={()=>handleClick(nav.name)}>
                        <ListItemText primary={nav.name} />
                        {open1[nav.name] ? <ExpandLess /> : <ExpandMore />}
                    </ListItem>
                    <Collapse in={open1[nav.name] } timeout="auto" unmountOnExit>
                        <List component="div" disablePadding>
                          { nestedMenu(nav.children)}
                        </List>
                    </Collapse>
                </div>
            )
        })
    }

之后,我nestedMenu在返回方法中使用 json 数据作为参数调用该函数

<List> {nestedMenu(Links.items)} </List>

谁能解释一下我在这一切中做错了什么,我一直在努力寻找问题所在。任何帮助将非常感激。

标签: reactjsmaterial-uireact-hooks

解决方案


问题是你改变了整个 open1 对象:

const handleClick = (param) => {
      setOpen1(prevState => ({[param]: !prevState[param]}));
};

例如,如果你有{p1:true, p2:false}并执行 handkeClick('p1'),open1 将是{p1:false}. 你需要保持 open1 的其他成员不变,只更新你想要的:

const handleClick = (param) => {
      setOpen1(prevState => 
          retrun {...prevState ,[param]: !prevState[param]}
      );
};

推荐阅读