对代码中涉及 `localStorage` 的部分的详细注释和讲解

在你提供的 React 代码中,localStorage 被用来存储和恢复树节点的展开/收起状态。以下是对代码中涉及 localStorage 的部分的详细注释和讲解,帮助更好地理解程序的逻辑:

// 递归渲染树结构
const CubeOutlineTree = ({ cube, initialTree }) => {
    // 从 localStorage 获取树的展开/合并状态
    const getSavedTreeState = () => {
        // 使用 queryUuid 作为键,从 localStorage 获取之前保存的树状态
        const savedState = localStorage.getItem(queryUuid); 
        // 如果获取到保存的状态,则返回该状态, 否则返回初始状态
        return savedState ? JSON.parse(savedState) : initialTree; 
    };

    // 使用 useState 管理树的状态,初始值从 localStorage 获取
    const [tree, setTree] = useState(getSavedTreeState);

    // 切换节点展开/收起状态的函数
    const toggleNodeVisibility = (nodes, itemId) => {
        return nodes.map(node => {
            // 找到对应的节点
            if (node.itemId === itemId) {
                // 切换该节点的 showChildren 状态,实现展开或收起
                return { ...node, showChildren: !node.showChildren };
            } else if (node.children) {
                // 如果节点有子节点,递归处理子节点
                return { ...node, children: toggleNodeVisibility(node.children, itemId) };
            }
            // 返回未修改的节点
            return node;
        });
    };

    // 递归渲染树结构
    const renderCubeOutlineTreeItems = (nodes) => {
        return nodes.map(node => {
            let margin_left = 0; // 默认节点 objType 为 'DimensionRole'
            let icon = <NorthEastIcon />; // 默认图标为箭头图标

            // 如果节点是 'HierarchyRole' 类型,调整样式和图标
            if (node.objType === 'HierarchyRole') {
                margin_left = 20;
                icon = <DehazeIcon />;
            }

            // 如果节点是 'MemberRole' 类型,进一步调整样式
            if (node.objType === 'MemberRole') {
                margin_left = 20 + (node.obj.member.level + 1) * 20; // 增加缩进
                icon = <PanoramaFishEyeIcon sx={{ fontSize: '16px' }} />;
            }

            return (
                <Box key={node.itemId}>
                    <Box sx={{ display: 'flex', alignItems: 'center' }}>
                        {/* 左侧展开/收起图标 */}
                        <Box
                            onClick={() => {
                                if (node.children.length === 0) return;
                                // 调用 toggleNodeVisibility 函数切换当前节点状态
                                const updatedTree = toggleNodeVisibility(tree, node.itemId);
                                setTree(updatedTree); // 更新状态
                                // 保持状态到 localStorage 中,使用 queryUuid 作为键
                                localStorage.setItem(queryUuid, JSON.stringify(updatedTree)); 
                            }}
                            sx={{ marginLeft: `${margin_left}px` }}
                        >
                            {/* 根据节点是否有子节点,决定展开/收起图标 */}
                            {
                                node.children.length === 0
                                    ? <Brightness1TwoToneIcon sx={{ color: '#e0e0e0' }} />
                                    : (node.showChildren ? <KeyboardArrowDownIcon /> : <KeyboardArrowRightIcon />)
                            }
                        </Box>
                        {/* 渲染拖拽树节点 */}
                        <DraggableTreeNode element={node} icon={icon} />
                    </Box>
                    <Box>
                        {/* 如果当前节点展开,则递归渲染子节点 */}
                        {node.showChildren && node.children && node.children.length > 0 && renderCubeOutlineTreeItems(node.children)}
                    </Box>
                </Box>
            );
        });
    };

    return (
        <Box>
            <h3>{cube.name}</h3>
            {/* 渲染树的节点项 */}
            {renderCubeOutlineTreeItems(tree)}
        </Box>
    );
};

注释讲解:

  1. localStorage 获取树的展开/收起状态:

    • 在组件初始化时,通过调用 getSavedTreeState 函数从 localStorage 获取先前保存的树结构状态。
    • 如果 localStorage 中存在保存的状态,则使用它恢复树的状态;如果没有(即首次加载),则使用传入的 initialTree 初始状态。
  2. 保存树的状态到 localStorage

    • 在每次点击节点进行展开或收起时,调用 toggleNodeVisibility 更新树的状态。
    • 更新后的状态通过 setTree 更新 React 的内部状态,并且通过 localStorage.setItem 将最新的树状态保存到浏览器的 localStorage 中。这样,用户在刷新页面后仍然能够看到上次保存的树结构状态。
  3. 更新节点状态与递归渲染:

    • toggleNodeVisibility 函数根据节点的 itemId 来切换其子节点是否显示的状态(showChildren)。通过递归方式确保每个节点的子节点状态也能更新。
    • 通过 renderCubeOutlineTreeItems 递归渲染树结构,确保每个节点及其子节点都被正确渲染。

总结:

  • 这部分代码的主要功能是处理一个多层级的树结构,通过 localStorage 保存和恢复节点的展开/收起状态,从而保持用户的交互体验。通过在用户每次点击展开/收起图标时更新树的状态,并将该状态持久化存储在 localStorage 中,确保刷新页面后,树的状态能够正确恢复。

posted on   及途又八  阅读(17)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示