如何修改React Box Shadow Generator实现删除层后保留原层名
解决Box Shadow Generator删除层后保留原层名的问题
当前实现的核心问题是层名完全依赖数组索引生成,删除中间层后数组索引重排,导致后续层的名称被自动修改。要保留原层名,需给每个阴影层添加独立标识和固定名称,不再依赖数组索引。
修改思路
- 给每个阴影对象添加
id(唯一标识)和name(固定层名)属性 - 将选中状态从存储数组索引改为存储选中层的
id - 所有依赖索引的操作(获取选中层、删除层等)改为通过
id查找对应元素 - 渲染层列表和控制区域标题时,使用层的
name属性而非索引
修改后的完整代码
import "./boxShadowGenerator.css"; import React, { useState, useRef, useEffect } from "react"; export const BoxShadowGenerator = () => { const [boxShadows, setBoxShadows] = useState([]); const [selectedLayerId, setSelectedLayerId] = useState(null); const buttonRefs = useRef({}); // 添加新层时生成唯一ID和固定层名 const addBoxShadow = () => { // 计算新层编号:取现有层最大编号+1,无现有层则从1开始 const maxLayerNumber = boxShadows.length ? Math.max(...boxShadows.map(layer => parseInt(layer.name.split(' ')[1]))) : 0; const newLayerNumber = maxLayerNumber + 1; const newBoxShadow = { id: Date.now(), // 用时间戳作为唯一标识 name: `Layer ${newLayerNumber}`, hOffset: 0, vOffset: 0, blurRadius: 0, spreadRadius: 0, color: "#000", }; const newBoxShadows = [...boxShadows, newBoxShadow]; setBoxShadows(newBoxShadows); setSelectedLayerId(newBoxShadow.id); // 默认选中新添加的层 }; // 通过ID删除指定层 const removeBoxShadow = (layerId) => { const newBoxShadows = boxShadows.filter(layer => layer.id !== layerId); setBoxShadows(newBoxShadows); // 如果删除的是当前选中层,自动选中第一个剩余层 if (selectedLayerId === layerId && newBoxShadows.length > 0) { setSelectedLayerId(newBoxShadows[0].id); } }; const copyToClipboard = () => { const boxShadow = boxShadows .map( ({ hOffset, vOffset, blurRadius, spreadRadius, color }) => `${hOffset}px ${vOffset}px ${blurRadius}px ${spreadRadius}px ${color}` ) .join(", "); navigator.clipboard.writeText(`box-shadow:${boxShadow};`); }; // 获取当前选中的层对象 const selectedLayer = boxShadows.find(layer => layer.id === selectedLayerId); useEffect(() => { if (selectedLayerId && buttonRefs.current[selectedLayerId]) { buttonRefs.current[selectedLayerId].focus(); } }, [selectedLayerId]); return ( <> <div className="BSG-main-container"> <div className="BSG-control-container"> <h2>Box Shadow Generator</h2> <div className="box-preview" style={{ boxShadow: boxShadows .map( ({ hOffset, vOffset, blurRadius, spreadRadius, color }) => `${hOffset}px ${vOffset}px ${blurRadius}px ${spreadRadius}px ${color}` ) .join(", "), }} ></div> {selectedLayer && ( <div> <h3>{selectedLayer.name}</h3> <div> <label htmlFor={`hOffset${selectedLayer.id}`}> Horizontal offset: </label> <input type="range" id={`hOffset${selectedLayer.id}`} min="-50" max="50" value={selectedLayer.hOffset} onChange={(e) => { setBoxShadows(boxShadows.map(layer => layer.id === selectedLayerId ? {...layer, hOffset: parseInt(e.target.value)} : layer )); }} /> </div> <div> <label htmlFor={`vOffset${selectedLayer.id}`}> Vertical offset: </label> <input type="range" id={`vOffset${selectedLayer.id}`} min="-50" max="50" value={selectedLayer.vOffset} onChange={(e) => { setBoxShadows(boxShadows.map(layer => layer.id === selectedLayerId ? {...layer, vOffset: parseInt(e.target.value)} : layer )); }} /> </div> <div> <label htmlFor={`blurRadius${selectedLayer.id}`}> Blur radius: </label> <input type="range" id={`blurRadius${selectedLayer.id}`} min="0" max="50" value={selectedLayer.blurRadius} onChange={(e) => { setBoxShadows(boxShadows.map(layer => layer.id === selectedLayerId ? {...layer, blurRadius: parseInt(e.target.value)} : layer )); }} /> </div> <div> <label htmlFor={`spreadRadius${selectedLayer.id}`}> Spread radius: </label> <input type="range" id={`spreadRadius${selectedLayer.id}`} min="-50" max="50" value={selectedLayer.spreadRadius} onChange={(e) => { setBoxShadows(boxShadows.map(layer => layer.id === selectedLayerId ? {...layer, spreadRadius: parseInt(e.target.value)} : layer )); }} /> </div> <div> <label htmlFor={`color${selectedLayer.id}`}>Color:</label> <input type="color" id={`color${selectedLayer.id}`} value={selectedLayer.color} onChange={(e) => { setBoxShadows(boxShadows.map(layer => layer.id === selectedLayerId ? {...layer, color: e.target.value} : layer )); }} /> </div> </div> )} <div className="buttons"> <button onClick={addBoxShadow}>Add Layer</button> {boxShadows.length > 0 && ( <> <button onClick={() => removeBoxShadow(selectedLayerId)}> Remove Layer </button> <button onClick={copyToClipboard}>Copy CSS to Clipboard</button> </> )} </div> </div> {boxShadows.length > 0 && ( <div className="box-shadow-list-container"> {boxShadows.map((boxShadow) => ( <button ref={(button) => (buttonRefs.current[boxShadow.id] = button)} key={boxShadow.id} className={`box-shadow-list-item ${selectedLayerId === boxShadow.id ? "selected" : ""}`} onClick={() => setSelectedLayerId(boxShadow.id)} > {boxShadow.name} </button> ))} </div> )} </div> </> ); };
内容的提问来源于stack exchange,提问作者SDhakZZZ
相关产品推荐
相关产品推荐

