react hook实现todoList和更复杂的的递归编辑树操作

在这里插入图片描述
之前有个兄弟问图上效果怎么实现出来,点击+号可以无限增加页面,新增的时候就是编辑状态,鼠标移开就是菜单列表,双击又变成可编辑的状态。于是我去简单实现了下,代码如下:

import React, { useState } from 'react';
import { Input } from 'antd';
import {
  DeleteOutlined
} from '@ant-design/icons';

function Menu() {
  const [menuItems, setMenuItems] = useState([]);
  const [activeId, setActiveId] = useState(null);

  const handleAddMenuItem = () => {
    const newId = Date.now();
    const newMenuItem = {
      id: newId,
      editing: true,
      text: '页面' + (menuItems?.length + 1)
    };
    setActiveId(newId)
    setMenuItems(prevItems => [...prevItems, newMenuItem]);
  };

  const handleDeleteMenuItem = (id) => {
    setMenuItems(prevItems => prevItems.filter(item => item.id !== id));
  };

  const handleToggleEdit = (id) => {
    setMenuItems(prevItems =>
      prevItems.map(item => {
        if (item.id === id) {
          return {
            ...item,
            editing: !item.editing
          };
        }
        return item;
      })
    );
  };

  const handleChangeText = (id, newText) => {
    setMenuItems(prevItems =>
      prevItems.map(item => {
        if (item.id === id) {
          return {
            ...item,
            text: newText
          };
        }
        return item;
      })
    );
  };

  const handleMenuItemClick = (id) => {
    if (id !== activeId) {
      setMenuItems(prevItems =>
        prevItems.map(item => ({
          ...item,
          editing: false
        }))
      );
    }
    setActiveId(id);
  };

  return (
    <div style={{width:'200px',height:'600px',backgroundColor:'#fff'}}>
      <button onClick={handleAddMenuItem}>新增</button>
      {menuItems.map(item => (
        <MenuItem
          key={item.id}
          item={item}
          onDelete={handleDeleteMenuItem}
          onToggleEdit={handleToggleEdit}
          onChangeText={handleChangeText}
          onClick={handleMenuItemClick}
          activeId={activeId}
        />
      ))}
    </div>
  );
}

function MenuItem({ item, onDelete, onToggleEdit, onChangeText, onClick, activeId }) {
  const handleDoubleClick = () => {
    onToggleEdit(item.id);
  };

  const handleChange = (e) => {
    onChangeText(item.id, e.target.value);
  };

  const handleDelete = () => {
    onDelete(item.id);
  };

  const handleClick = () => {
    onClick(item.id);
  };

  if (item.id === activeId && item.editing) {
    return (
      <div style={{width:'200px'}}>
        <Input type="text" value={item.text} onChange={handleChange} onBlur={handleDoubleClick} autoFocus />
      </div>
    );
  }

  return (
    <div style={{width:'200px',padding:'5px',backgroundColor:item.id === activeId?'rgb(218, 235, 254)':'#fff',display:'flex',justifyContent:'space-between'}} onClick={handleClick} onDoubleClick={handleDoubleClick}>
      <span>{item.text}</span>
      <DeleteOutlined onClick={handleDelete} />
    </div>
  );
}

export default Menu;

效果如下:
在这里插入图片描述
在这里插入图片描述
好了现在开始上强度,如果是下图效果那么该怎么做呢?

在这里插入图片描述
感兴趣的可以自己想一下哟!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值