React18-树形菜单-递归

文章目录

    • 案例分析
    • 技巧
    • 通信
    • 展示效果
    • 实现代码
      • 技巧点
      • 技巧点
    • 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[Python从零到壹] 七十四.图像识别及经典案例篇之文字图像区域定位及提取分析

欢迎大家来到“Python从零到壹”&#xff0c;在这里我将分享约200篇Python系列文章&#xff0c;带大家一起去学习和玩耍&#xff0c;看看Python这个有趣的世界。所有文章都将结合案例、代码和作者的经验讲解&#xff0c;真心想把自己近十年的编程经验分享给大家&#xff0c;希望…

力扣67. 二进制求和算法

一、【写在前面】 这道题需要&#xff0c;给你两个字符串比如 a "1010", b "1011"答案是&#xff1a;"10101" 然后需要你给出计算结果&#xff0c;那么我们很容易想到两种做法 1. 调库做法&#xff1a;直接转化为整数&#xff0c;然后用内…

2024年AMC8往年真题练一练和答案详解(6),还有全真模拟题

今天是1月13日&#xff0c;2024年AMC8正式比赛已经倒计时了&#xff0c;昨天AMC主办方给所有参赛选手发了短信通知&#xff0c;关于模拟竞赛的操作方式和实际比赛的要求指南&#xff0c;大家一定要认真阅读&#xff0c;严格按指南操作&#xff0c;六分成长也会详细为大家解读和…

【剪枝】【广度优先】【深度优先】488祖玛游戏

作者推荐 【动态规划】458:可怜的小猪 涉及知识点 剪枝 广度优先 深度优先 488祖玛游戏 在这个祖玛游戏变体中&#xff0c;桌面上有 一排 彩球&#xff0c;每个球的颜色可能是&#xff1a;红色 ‘R’、黄色 ‘Y’、蓝色 ‘B’、绿色 ‘G’ 或白色 ‘W’ 。你的手中也有一些…

上海AI实验室等开源,音频、音乐统一开发工具包Amphion

上海AI实验室、香港中文大学数据科学院、深圳大数据研究院联合开源了一个名为Amphion的音频、音乐和语音生成工具包。 Amphion可帮助开发人员研究文本生成音频、音乐等与音频相关的领域&#xff0c;可以在一个框架内完成&#xff0c;以解决生成模型黑箱、代码库分散、缺少评估…

C语言天花板——指针(进阶2)

好久不见了各位&#xff0c;甚是想念啊&#xff01;&#xff01;&#xff01;&#x1f3b6;&#x1f3b6;&#x1f3b6; 文章接上次的指针(进阶1)(http://t.csdnimg.cn/c39SJ)&#xff0c;我们继续发车咯&#x1f697;&#x1f697;&#x1f697; 五、函数指针 上次我们只是浅…

py的函数讲解

前言:本章节我们来讲函数&#xff0c;主播略微感觉到有点小难&#xff0c;友友们需要认真看 目录 一.初始函数 1.1关于函数 1.2举例 1.3小结 二.函数的基础语法 2.1关于函数的语法 2.2举例 2.3小结 三.函数的参数 3.1关于函数的参数 3.2举例 3.3小结 四.函数的返回…

【AI】 AIOTSummary

智能物联网(AIoT)是2018年兴起的概念,指系统通过各种信息传感器实时采集 各类信息(一般是在监控、互动、连接情境下的),在终端设备、边缘域或云中心 通过机器学习对数据进行智能化分析,包括定位、比对、预测、调度等。智能物联网(AIoT)是2018年兴起的概念,指系统通过…

UCB Data100:数据科学的原理和技巧:第十三章到第十五章

十三、梯度下降 原文&#xff1a;Gradient Descent 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 学习成果 优化复杂模型 识别直接微积分或几何论证无法帮助解决损失函数的情况 应用梯度下降进行数值优化 到目前为止&#xff0c;我们已经非常熟悉选择模型和相应损…

2023年全国职业院校技能大赛软件测试赛题—单元测试卷⑨

单元测试 一、任务要求 题目1&#xff1a;根据下列流程图编写程序实现相应分析处理并显示结果。返回文字“xa*a*b的值&#xff1a;”和x的值&#xff1b;返回文字“xa-b的值&#xff1a;”和x的值&#xff1b;返回文字“xab的值&#xff1a;”和x的值。其中变量a、b均须为整型…

VMware workstation安装MX-23.1虚拟机并配置网络

VMware workstation安装MX-23.1虚拟机并配置网络 MX Linux是基于Debian稳定分支的面向桌面的Linux发行&#xff0c;采用Xfce作为缺省桌面&#xff0c;是一份中量级操作系统。该文档适用于在VMware workstation平台安装MX-23.1虚拟机。 1.安装准备 1.1安装平台 Windows 11 …

Smallpdf扫描、转换、压缩、编辑、签名PDF

【应用名称】&#xff1a;Smallpdf: 扫描、转换、压缩、编辑、签名PDF 【适用平台】&#xff1a;#Android 【软件标签】&#xff1a;#Smallpdf 【应用版本】&#xff1a;1.71.0 【应用大小】&#xff1a;150MB 【软件说明】&#xff1a;通过 Smallpdf&#xff0c;您可以&…

extern static 在linux 和 qt下差别

从五个点来说 1.p3.h 中 静态定义一个const的int 变量并且赋值 2.p5.h 声明函数test2的定义 3. 直接extern 引用声明 test1() 函数 而不是像p5.h一样 把函数声明写到头文件 在别的.c文件直接包含头文件 第二点和第三点 是引用声明函数的两种用法 4.main函数 中static静态定…

Vue3+Vite连接高德地图JS API——地图显示、输入搜索

1 开通高德地图Web端JS API服务 1、进入高德地图API官网&#xff08;https://lbs.amap.com/&#xff09;&#xff1a; 2、注册登录。 3、进入控制台。 4、点击“应用管理”&#xff0c;点击“我的应用”&#xff0c;创建新应用。 5、添加Key&#xff0c;服务平台选择“Web端&…

海外云手机助力企业拓展海外市场

在当前全球化的商业环境中&#xff0c;由于政策限制&#xff0c;许多企业面临着无法顺利将产品推广到国外的困境&#xff0c;使得海外市场的机遇白白流失。而随着科技的不断创新&#xff0c;一种解决企业海外拓展困境的工具应运而生&#xff0c;那就是海外云手机。本文将深入探…

使用Navicat导入csv数据至mysql

问题 使用Navicat导入csv数据至mysql 详细问题 笔者有已进行数据处理的csv&#xff0c;需要将数据信息导入mysql中 解决方案 步骤1、建立数据表&#xff0c;字段信息&#xff08;最好&#xff09;与csv字段信息保持一致&#xff0c;方便后续导入。 具体的&#xff0c;双击…

什么情况下考虑同时接入SD-WAN与MPLS

在企业网络架构中&#xff0c;SD-WAN和MPLS&#xff08;多协议标签交换&#xff09;都是常见的网络连接解决方案。而有时候&#xff0c;企业可能面临一种情况&#xff0c;即需要同时接入SD-WAN和MPLS。本文将探讨在什么情况下考虑同时使用这两种网络连接方式&#xff0c;并分析…

NVMe over TCP高性能文件存储,让未来照进现实,400us

你真的懂NVMe吗&#xff1f; 在说NVMe之前&#xff0c;我们觉得有必要先聊一聊NVM&#xff08;Non-Volatile Memory&#xff09;&#xff0c;即非易失性内存。从名字上看就知道&#xff0c;NVM是一种类内存式&#xff08;访问及寻址方式类似&#xff09;的设备&#xff0c;它必…

Postgresql常见(花式)操作完全示例

案例说明 将Excel数据导入Postgresql&#xff0c;并实现常见统计&#xff08;数据示例如下&#xff09; 导入Excel数据到数据库 使用Navicat工具连接数据库&#xff0c;使用导入功能可直接导入&#xff0c;此处不做过多介绍&#xff0c;详细操作请看下图&#xff1a; 点击“下…

vivado Revision Control

2020.2 只需要git 管理 prj.xpr 和 prj.srcs/ https://china.xilinx.com/video/hardware/ip-revision-control.html Using Vivado Design Suite with Revision Control https://www.xilinx.com/video/hardware/vivado-design-suite-revision-control.html http://www.xi…