React18-树形菜单-递归

news2024/11/19 5:47:50

文章目录

    • 案例分析
    • 技巧
    • 通信
    • 展示效果
    • 实现代码
      • 技巧点
      • 技巧点
    • Refer to

案例分析

https://github.com/dL-hx/manager-fe/commit/85faf3b1ae9a925513583feb02b9a1c87fb462f7

从接口获取城市数据,渲染出一个树形菜单
要求:
可以展开和收起

技巧

  1. 学会递归渲染出一个树形菜单, 并点击后可以展开和收起
  2. 通过对数据上添加控制字段(show)避免在子组件添加各种同步的useState,等字段.保证单向数据流向, 来简化问题.

通信

父子通信

展示效果

在这里插入图片描述

实现代码

在这里插入图片描述
在这里插入图片描述
src\views\TreeMenu\index.tsx

import TreeMenu from "./TreeMenu";
export default TreeMenu

技巧点

  1. 调用pulic/citydata.json数据
  2. 通过原数据添加show字段,递归处理.为每一个item添加show字段
  3. 当再次点击item选项时候,根据原数据上的show字段进行控制, 递归修改源数据对应的id(判断条件找到对应item, if (item.value === id) ).
    将其取反后setData
    对于接口源数据没有返回的ui控制字段,前端需要自己添加

因为是react, 对引用数据修改要注意需要生成新数据后在setData
src\views\TreeMenu\TreeMenu.tsx

import { Button } from "antd";
import { useState, useEffect } from "react";
import Tree from "./Tree";
export default function TreeMenu() {
    const [data, setData] = useState([])

    useEffect(() => {
        fetch('/citydata.json').then(res => res.json()).then(res => {
            setData(recursionAddProps(res))
        })
    }, [])

    // 当数据请求过来后,我们要递归式给每一个数据加一个属性,用来控制是否展开功能
    const recursionAddProps = (data) => {
        // 在item 上加一个属性
        // show: true 则展开,  false 折叠
        return data.map((item) => {
            item.show = false
            // 递归式自己调用自己
            if (item.children) {
                recursionAddProps(item.children)
            }
            return item
        })
    }

    /**
     * 
     * @param data 源数据
     * @param id 点击的id选项
     * @returns 
     */
    const recursionEditProps = (data, id) => {
        // 在item 上加一个属性
        // show: true 则展开,  false 折叠
        return data.map((item) => {
            if (item.value === id) { // 判断条件: 找到对应id在取反
                item.show = !item.show // 取反
            } 
            // 递归式自己调用自己
            if (item.children) {
                recursionEditProps(item.children, id)
            }
            return item
        })
    }

    // 获取到子组件传递过来的数据
    const setShow = (child) => {
        // item.show = true
        // const newData = data.map((item) => {
        //     if (item['value'] === child.value) {
        //         // @ts-ignore
        //         item['show'] = !child.show
        //     }
        //     return item
        // })
        // setData(newData)

        // 需要递归处理这个show展开 
        // console.log(recursionEditProps(data, child.value));
        // 通过item-id,把数据中的show 改为true
        setData(recursionEditProps(data, child.value))
    }
    return <div>
        <Tree data={data} setShow={setShow}></Tree>
    </div>
}

技巧点

  1. 递归调用自身
  2. 通过为父组件原数据添加show字段, 子组件修改父组件数据结构的show字段来控制,子组件是否展示
    因为是单向数据流, 数据控制视图, 通过递归完成

src\views\TreeMenu\Tree.tsx

import Tree from './Tree'

export default ({ data, show=true, setShow }: any) => {
    console.log(data);

    return <ul style={{display: show? 'block': 'none'}}>
        {
            Array.isArray(data) && data.length && data.map(item => {
                return <li key={item.value} onClick={(event)=>{
                    // 清除冒泡
                    event.stopPropagation()
                    setShow(item)
                }}>
                    {item.value}
                    {/* 递归组件 */}
                    {
                        item.children && item.children.length && <Tree data={item.children} show={item.show} setShow={setShow}/>
                    }
                </li>
            })
        }
    </ul>
}

/public/citydata.json

[
    {
        "lable": "北京市",
        "value": "北京市",
        "children": [
            {
                "lable": "东城区",
                "value": "东城区",
                "children": [
                    {
                        "lable": "东城区-0",
                        "value": "东城区-0"
                    },
                    {
                        "lable": "东城区-1",
                        "value": "东城区-1"
                    },
                    {
                        "lable": "东城区-2",
                        "value": "东城区-2"
                    }
                ]
            },
            {
                "lable": "西城区-1",
                "value": "西城区",
                "children": [
                    {
                        "lable": "西城区-0",
                        "value": "西城区-0"
                    },
                    {
                        "lable": "西城区-1",
                        "value": "西城区-1"
                    },
                    {
                        "lable": "西城区-2",
                        "value": "西城区-2"
                    }
                ]
            },
            {
                "lable": "海淀区-2",
                "value": "海淀区-2"
            }
        ]
    },
    {
        "lable": "西安市",
        "value": "西安市",
        "children": [
            {
                "lable": "长安区-0",
                "value": "长安区-0"
            },
            {
                "lable": "桥西区-1",
                "value": "桥西区-1"
            },
            {
                "lable": "新华区-2",
                "value": "新华区-2"
            }
        ]
    },
    {
        "lable": "天津市",
        "value": "天津市"
    }
]

Refer to

https://www.bilibili.com/video/BV19W4y1p7eu

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1375771.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows开机后,Docker失败:Commoncauses include access rights issues

这种错误看似已经跟你说很清楚了&#xff0c;但是看国外docker社区也提到这个问题&#xff0c;一大堆回答解决了别人的问题&#xff0c;但未必解决你的。我写自己的方案&#xff0c;可能也未必适合你&#xff0c;如果要说Root Cause根源就是windows的虚拟化功能开启的问题。 An…

(vue)el-table表格最小/自动高度设置

(vue)el-table表格最小/自动高度设置 <el-table:data"tableData"size"mini"borderstyle"min-height:100px" //重点 ><el-table-column align"center" label"参数名称" prop"parametersName" />... &l…

web网页首页布局

效果展示&#xff1a; html代码&#xff1a; <!doctype html> <html> <head><meta charset"utf-8"><meta http-equiv"X-UA-Compatible" content"IEedge,chrome1"> <meta name"viewport" content&qu…

Linux:centos yum安装指令指南

如果我们在Linux中输入命令发现该命令没有的时候&#xff0c;我们就可以通过yum来安装这个命令 具体分为两步&#xff1a;搜索&#xff0c;安装 搜索 首先搜索centos yum 安装 指令 以zip指令为例&#xff0c;在搜索框中输入centos yum 安装zip 安装 复制安装命令到shell…

Vue2x的自定义指令和render函数使用自定义指令

在某些情况下&#xff0c;我们需要对底层DOM进行操作&#xff0c;而内置的指令不能满足需求&#xff0c;就需要自定义指令。一个自定义指令由一个包含类似组件的生命周期的钩子的对象来定义&#xff0c;钩子函数会接收到指令所绑定的元素作为参数。 定义指令 常用两种方式进行…

前端开发Docker了解

1&#xff0c;docker简介 docker主要解决了最初软件开发环境配置的困难&#xff0c;完善了虚拟机部署的资源占用多&#xff0c;启动慢等缺点&#xff0c;保证了一致的运行环境&#xff0c;可以更轻松的维护和扩展。docker在linux容器的基础上进行了进一步的封装&#xff0c;提…

几款优秀科学开源计算软件介绍

有一些比较优秀的软件&#xff0c;它们在科学计算、数据处理和分析方面具有广泛的应用和功能。以下是一些比较知名的软件&#xff1a; SciPy&#xff1a;SciPy是一个非常流行的科学计算库&#xff0c;提供了大量的数学函数和算法&#xff0c;用于解决各种科学问题。它支持多种操…

商城小程序(8.购物车页面)

目录 一、商品列表区域1、渲染购物车商品列表的标题区域2、渲染商品列表区域的基本结构3、为my-goods组件封装radio勾选状态4、为my-goods组件封装radio-change事件5、修改购物车中商品的选择状态6、为my-goods组件封装NumberBox7、为my-goods封装num-change事件8、修改购物车商…

Sqlmap注入参数

Sqlmap注入参数 &#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f32d;&#x1f32d;&#x1f32d;&#x1f32d;&#x1f32d;&#x1f32d;&#x1f32d;❤️❤️❤️❤️❤️❤️❤️&#x1f968;&#x1f968;&…

题目:七段码(蓝桥OJ 595)

问题描述&#xff1a; 解题思路&#xff1a; 枚举每一种可能组合&#xff08;可以使用二进制数表示&#xff0c;每一个二进制就是一种组合&#xff09;&#xff0c;在判断是否符合题目要求的每一个发光灯管相邻&#xff08;使用并查集方法确定&#xff0c;当每一个发光…

NumPy 数据操作实用指南:从基础到高效(下)

文章接上篇&#xff1a; In [53]: from PIL import Image In [60]: dog Image.open(./dog.jpg) dog . . . In [61]: dog_datanp.array(dog) # 图片数据是ndarray # 彩色照片三维&#xff1a;高度&#xff0c;宽度&#xff0c;像素&#xff08;表示不同颜色&#xff09;&…

小程序基础库与Android之间通信优化的可能

最近在学习graalvm&#xff0c;发现有一个graaljs项目&#xff0c;项目中介绍可以让java与JavaScript做数据转换&#xff0c;比如JavaScript中可以使用java的数据类型与结构。突然想到之前遇到的一个问题&#xff0c;小程序中开发的代码和基础库的部分代码都是j2v8来执行的&…

易安联参与制定的《面向云计算的零信任体系》行业标准即将实施

中华人民共和国工业和信息化部公告2023年第38号文件正式发布行业标准&#xff1a;YD/T 4598.2-2023《面向云计算的零信任体系 第2部分&#xff1a;关键能力要求》及YD/T 4598.3-2023《面向云计算的零信任体系 第3部分&#xff1a;安全访问服务边缘能力要求》&#xff0c;并于20…

如何将ArcGIS工程文件迁移到ArcGIS Pro内

当你刚接触ArcGIS Pro的时候&#xff0c;尝试新建一个工程文件会发现工程文件的后缀已经改变&#xff0c;那么以前在ArcGIS内辛苦制作的工程文件是否就不能在ArcGIS Pro内使用了&#xff0c;答案是否定的&#xff0c;对此Esri也给出了解决方案&#xff0c;这里为大家介绍一下迁…

数字化校园实验室综合管理平台|推动实验室创新发展新引擎

一、数字化建设目标 实验室数字化指的是运用新一代的人工智能、大数据、互联网技术、物联网技术、云计算技术、人体感应技术、语音技术、生物识别技术、手机APP等技术&#xff0c;实现各个业务间数据流和任务流的互通互联&#xff0c;将实验室管理过程中涉及的对象&#xff0c…

vue2 el-table行悬停时弹出提示信息el-popover

实现方法&#xff0c;用到了cell-mouse-enter、cell-mouse-leave两个事件&#xff0c;然后在表格的首列字段中&#xff0c;加个el-popover组件&#xff0c;当然你也可以选择在其他字段的位置来显示提示框&#xff0c;看自己的需求了。 示例代码&#xff1a; <el-table cell…

GLES学习笔记---立方体贴图(一张图)

一、首先看一张效果图 立方体贴图 二、纹理坐标划分 如上图是一张2D纹理&#xff0c;我们需要将这个2D纹理贴到立方体上&#xff0c;立方体有6个面&#xff0c;所以上面的2D图分成了6个面&#xff0c;共有14个纹理坐标 三、立方体 上边的立方体一共8个顶点坐标&#xff0c;范围…

Web3社交治理:用户参与决策的新模式

Web3时代的到来不仅仅带来了区块链技术的创新&#xff0c;还为社交治理带来了全新的模式。传统社交平台上的决策权通常集中在平台的运营方&#xff0c;而Web3社交治理的兴起意味着用户能够更直接地参与到社交平台的决策过程中。本文将深入探讨Web3社交治理的背景、工作原理以及…

9.云原生存储之ceph在k8s中应用及问题处理

文章目录 ceph应用场景ceph应用在k8s集群外使用块设备ceph客户端配置创建块挂载使用删除pool 在k8s集群内使用块设备创建块池和StorageClass使用存储 块存储映射问题处理问题现象事件分析csi-rbdplugin pod日志分析问题小结CentOS 7 编译安装 nbd 模块nbd内核模块介绍安装 nbd …

1.5计算机网络的分类

1.5计算机网络的分类 1.5.1按照网络的作用范围进行分类 1、广域网WAN 广域网WAN&#xff08;WideAreaNetwork&#xff09;&#xff1a;广域网的作用范围通常为几十到几千公里&#xff0c;因而有时也称为远程网(longhaulnetwork)。广域网是互联网的核心部分&#xff0c;其任务…