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 改为truesetData(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.mzph.cn/news/623761.shtml

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

相关文章

力扣-三数之和

三数之和 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元组。…

16. 从零用Rust编写正反向代理, 反向代理upstream源码实现

wmproxy wmproxy是由Rust编写&#xff0c;已实现http/https代理&#xff0c;socks5代理&#xff0c; 反向代理&#xff0c;静态文件服务器&#xff0c;内网穿透&#xff0c;配置热更新等&#xff0c; 后续将实现websocket代理等&#xff0c;同时会将实现过程分享出来&#xff…

gramine运行nodejs例程

首先&#xff0c; 修改js例程代码&#xff1a; const { Web3 } require(web3); const rpcURL "https://sepolia.infura.io/v3/40b89bc0f5584056b19626b521ee5874"; const web3 new Web3(rpcURL); const address "0xde51E698b4585Af1C8322cc084ABbdbDcfe533…

C++力扣题目450--删除二叉搜索树中的节点

给定一个二叉搜索树的根节点 root 和一个值 key&#xff0c;删除二叉搜索树中的 key 对应的节点&#xff0c;并保证二叉搜索树的性质不变。返回二叉搜索树&#xff08;有可能被更新&#xff09;的根节点的引用。 一般来说&#xff0c;删除节点可分为两个步骤&#xff1a; 首先…

Generalized Focal Loss论文个人理解

论文地址&#xff1a;Generalized Focal Loss: Towards Efficient Representation Learning for Dense Object Detection 论文解决问题 研究人员最近更加关注边界框的表示(representation)及其定位质量估计&#xff08;LQE&#xff0c;本论文中指的是IoU score&#xff09;&a…

将YOLO数据集转成COCO格式,单个文件夹转为单个json文件,例如.../images/train转为instance_train.json

写在前面 参考链接&#xff1a;objectdetection-tricks/tricks_4.py 相关视频教学&#xff1a;tricks_4 用于yolov5和v7中的yolo格式转换coco格式的脚本.(如何在v5和v7中输出ap_small,ap_middle,ap_large coco指标)还可以参考相关的VOC转COCO的方式&#xff1a;damo-yolo/voc2…

R语言【paleobioDB】——pbdb_reference():通过参数请求获得多条参考文献的基本信息

Package paleobioDB version 0.7.0 paleobioDB 包在2020年已经停止更新&#xff0c;该包依赖PBDB v1 API。 可以选择在Index of /src/contrib/Archive/paleobioDB (r-project.org)下载安装包后&#xff0c;执行本地安装。 Usage pbdb_references (...) Arguments 参数【...】…

MtimeMtimecmp

Mtime: 实时time计数器&#xff0c;可读可写&#xff1b;mtime必须按照一个固定的频率递增&#xff1b;如果count overflow了&#xff0c;则mtime的值需要卷绕&#xff1b;对于32/64的系统来说&#xff0c;mtime的值都是64bits的&#xff1b; 与mtime对应的&#xff0c;还有一…

【架构师成长之领域驱动开发】

架构师成长之路 1. 如何构建高质量应用&#xff1f;2. 三大设计原则&#xff1f;3.DDD妙招4. 最终的改造结果5.模型 项目中的“坏”味道 可维护性差&#xff1a;大量的第三方模块影响核心代码的稳定性可扩展性差&#xff1a;业务逻辑与数据存储相互依赖&#xff0c;无法复用可测…

项目中使用iframe引入html 解决路由错乱问题以及父子组件传值调用方法

iframe与外部之间传值 父组件 <iframeid"iframe"src"luckysheet/index.html"frameborder"0"scrolling"no"style"width: 100%; height: 60vh; border: 0"/>const frame document.getElementById(iframe);frame.onloa…

Python综合练习之图表

文章目录 文件目录如下图标效果timeline_bar_with_graphic.htmltable_base.html articles.jsonarticlesData.pyarticlesEchartsEntity.pyarticlesEntity.py Python学习了约一个月的时间&#xff0c;这是一篇综合练习的文章。主要做的内容是通过封装对象、实现抽象方法生成统计图…

不可预测的市场中,为何有人持续胜出?

为什么经济学家和证券分析师难以预测经济或股价走势&#xff0c;而少数投资大师却能几十年持续复利&#xff1f;这两个问题看似矛盾&#xff0c;既然无法预测&#xff0c;为何又能产生确定性的赚钱结果呢&#xff1f; 有人认为这是因为幸存者偏差。然而&#xff0c;三十年以上连…

优优嗨聚集团:债务逾期,如何应对与解决?

在现代社会&#xff0c;债务问题已成为越来越多人面临的难题。债务逾期不仅会给个人带来巨大的经济压力&#xff0c;还会影响个人信用记录&#xff0c;甚至可能引发法律纠纷。那么&#xff0c;当债务逾期时&#xff0c;我们应该如何应对与解决呢&#xff1f; 一、了解债务情况 …

14.STL 常用算法

14、STL常用算法 概述&#xff1a; 算法主要是由头文件 、、 组成 是所有STL头文件中最大的一个&#xff0c;范围涉及到比较、 交换、查找、遍历操作、复制、修改等等 体积很小&#xff0c;只包括几个在序列上面进行简单数学运算的模板函数 定义了一些模板类,用以声明函数对象…

1.3 面试经典150题 - 删除有序数组中的重复项

删除有序数组中的重复项 class Solution:def removeDuplicates(self, nums: List[int]) -> int:# 处理边界数据if not nums: return 0if len(nums) 1: return 1# 两个指针&#xff0c;一个记录当前有多少个不重复值的个数&#xff0c;一个记录最新遍历到的值count 1tmp …

C# ObjectArx 绘制表格并设置单元格合并

第一行默认是标题&#xff0c;可设置行【RowType】进行设置类型 Document doc Application.DocumentManager.MdiActiveDocument;using (Transaction tr doc.TransactionManager.StartOpenCloseTransaction()){BlockTable bt tr.GetObject(doc.Database.BlockTableId, OpenMo…

GZ075 云计算应用赛题第9套

2023年全国职业院校技能大赛&#xff08;高职组&#xff09; “云计算应用”赛项赛卷9 某企业根据自身业务需求&#xff0c;实施数字化转型&#xff0c;规划和建设数字化平台&#xff0c;平台聚焦“DevOps开发运维一体化”和“数据驱动产品开发”&#xff0c;拟采用开源OpenSt…

Python3 中常用字符串函数介绍

介绍 Python 中有几个与 字符串数据类型相关的内置函数。这些函数让我们能够轻松修改和操作字符串。我们可以将函数视为在代码元素上执行的操作。内置函数是在 Python 编程语言中定义的&#xff0c;并且可以随时供我们使用的函数。 在本教程中&#xff0c;我们将介绍在 Pytho…

导轨式信号隔离变送器比例阀门线性驱动器4-20mA/0-5V/0-10V转0-165mA/0-80mA/0-1A/0-2A/0-4A

主要特性 精度、线性度误差等级&#xff1a; 0.1、0.2、0.5 级4-20mA/0-5V/0-10V 等标准信号输入0~100mA/0~500mA/0~1A/0-5A 等电流信号输出0~1V(max 2A)/0~10V/0-24V(max 5A) 等电压信号输出信号输入/信号输出 3000VDC 隔离辅助电源&#xff1a;12V、15V 或 24V 直流单电源供…

【微服务】日志搜集elasticsearch+kibana+filebeat(单机)

日志搜集eskibanafilebeat&#xff08;单机&#xff09; 日志直接输出到es中&#xff0c;适用于日志量小的项目 基于7.17.16版本 主要配置在于filebeat&#xff0c; es kibana配置改动不大 环境部署 es kibana单机环境部署 略 解压即可 常见报错&#xff0c;百度即可。 记录…