You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;

关键说明

  1. 路由跳转问题:原Link的to属性依赖异步更新的state,会导致传递旧值,改用useNavigate手动跳转可确保传递最新输入内容。
  2. URL编码处理:用encodeURIComponent和decodeURIComponent处理空格、特殊字符,避免URL解析错误。
  3. JointJS属性修复:原代码中cell.attr.fill和cell.content是错误写法,需用cell.attr("body/fill")和cell.attr("label/text")获取元素属性。

内容的提问来源于stack exchange,提问作者Nov Joy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 09:09:51