React中如何将MyDiagrams的NewDiagramName传递至EditDiagram组件
如何将MyDiagrams中输入的图表名称传递到EditDiagram的保存函数中
我需要把用户在MyDiagrams.jsx的prompt里输入的NewDiagramName传递到EditDiagram.jsx,并在EditDiagram的handleSave函数中,将其作为图表标题填入createDiagram的title参数里。技术栈为React、JSX、JointJS,尝试用params传递但未成功。
解决方案步骤
1. 调整路由配置
确保路由同时支持**编辑已有图表(带ID)和创建新图表(带名称)**两种场景,以react-router-dom v6+为例,修改路由配置文件:
// 示例:App.js或专门的路由配置文件 import { Routes, Route } from 'react-router-dom'; import MyDiagrams from './path/to/MyDiagrams'; import EditDiagram from './path/to/EditDiagram'; function App() { return ( <Routes> <Route path="/my-diagrams" element={<MyDiagrams />} /> {/* 编辑已有图表:带diagramId参数 */} <Route path="/edit-diagram/:diagramId" element={<EditDiagram />} /> {/* 创建新图表:带newName参数 */} <Route path="/create-diagram/:newName" element={<EditDiagram />} /> </Routes> ); }
2. 修复MyDiagrams.jsx的跳转逻辑
原代码中Link的to属性会提前渲染旧的state值,改用手动跳转确保传递最新输入的名称:
import { useEffect, useState } from "react"; import { Link, useNavigate } from "react-router-dom"; // 引入useNavigate import { diagramService } from "../Services/diagram.service"; import plusImg from "../../images/plus.png"; import "../Styles/MyDiagrams.css"; function MyDiagrams() { const [myDiagrams, setMyDiagrams] = useState([]); const navigate = useNavigate(); // 初始化导航方法 useEffect(() => { loadDiagrams(); }, []); const loadDiagrams = async () => { const diagrams = await diagramService.getAllDiagrams(); setMyDiagrams(diagrams); }; const handleClick = () => { const enteredName = prompt("Enter name to the new diagram:"); if (enteredName) { // 校验用户输入非空 // 编码特殊字符后跳转,避免URL解析异常 navigate(`/create-diagram/${encodeURIComponent(enteredName)}`); } }; return ( <div> <nav className="navbar"> <h2 className="title">Your diagrams</h2> </nav> {myDiagrams.map((diagram) => ( <Link className="mlink" key={diagram.id} to={`/edit-diagram/${diagram.id}`} > <div>{diagram.title}</div> </Link> ))} {/* 将Link改为普通可点击元素,避免自动跳转冲突 */} <div onClick={handleClick} style={{ cursor: "pointer" }}> <img src={plusImg} alt="Add New" /> </div> </div> ); } export default MyDiagrams;
3. 在EditDiagram.jsx中获取并使用标题
从params中提取新图表名称,存入state后在保存时使用:
import { useEffect, useMemo, useRef, useState } from "react"; import { useParams } from "react-router-dom"; import DiagramMenu from "../Components/DiagramMenu"; import { diagramService } from "../Services/diagram.service"; import * as joint from "jointjs"; function EditDiagram() { const [paper, setPaper] = useState(new joint.dia.Paper()); const [historyStack, setHistoryStack] = useState([]); const [diagramTitle, setDiagramTitle] = useState(""); // 存储图表标题 const paperRef = useRef(); const graph = useMemo(() => new joint.dia.Graph(), []); const params = useParams(); useEffect(() => { if (params.newName) { // 解码URL中的名称,恢复特殊字符 setDiagramTitle(decodeURIComponent(params.newName)); } else if (params.diagramId) { // 编辑已有图表时,加载并设置原有标题 const loadDiagram = async () => { const diagramData = await diagramService.getDiagramById(params.diagramId); diagramData && buildDiagram(diagramData); diagramData && setDiagramTitle(diagramData.title); }; loadDiagram(); } }, [params]); // 原有buildDiagram、buildDiagramCell等代码保持不变... const handleSave = async () => { const cells = graph.getCells().map((cell) => ({ positionX: cell.position().x, positionY: cell.position().y, serialNumber: 66, width: cell.getBBox().width, height: cell.getBBox().height, color: cell.attr("body/fill"), // 修复JointJS属性获取方式 content: cell.attr("label/text"), // 修复JointJS属性获取方式 startIndex: 1, endIndex: 5435, })); const links = graph.getLinks().map((link) => { const labelText = link.label(0)?.attrs?.text?.text || ""; // 增加空值容错 if (typeof link.id === "string") { return { content: labelText, fromCellId: link.source().id, toCellId: link.target().id, }; } return { id: link.id, content: labelText, fromCellId: link.source().id, toCellId: link.target().id, }; }); const response = await diagramService.createDiagram({ title: diagramTitle || "Untitled Diagram", // 使用获取到的标题,添加默认值兜底 description: "description", links, cells, }); console.log("AFTER CREATE"); }; // 原有handleCreateCell、saveToHistory等代码保持不变... return ( <div> <DiagramMenu onSave={handleSave} onCreate={handleCreateCell} /> <div id="myholder" ref={paperRef}></div> <div className="canvas-container"> <div id="secondmyholder"></div> </div> </div> ); } export default EditDiagram;
关键说明
- 路由跳转问题:原Link的
to属性依赖异步更新的state,会导致传递旧值,改用useNavigate手动跳转可确保传递最新输入内容。 - URL编码处理:用
encodeURIComponent和decodeURIComponent处理空格、特殊字符,避免URL解析错误。 - JointJS属性修复:原代码中
cell.attr.fill和cell.content是错误写法,需用cell.attr("body/fill")和cell.attr("label/text")获取元素属性。
内容的提问来源于stack exchange,提问作者Nov Joy
相关产品推荐
相关产品推荐

