Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

自定义节点组件调用graph #2257

Closed
BrickerZou opened this issue Jun 23, 2022 · 21 comments
Closed

自定义节点组件调用graph #2257

BrickerZou opened this issue Jun 23, 2022 · 21 comments
Assignees
Labels
type: documentation 文档 Issues related to project documentation and our official site

Comments

@BrickerZou
Copy link

Describe the bug

我通过props传递graph到自定义节点组件,进行一些graph的方法,但这似乎不是正确的做法
image

当我打印出ToJson()时,其props中的graph无限递归
image

Your Example Website or App

https://codesandbox.io/s/restless-cdn-21ulm3?file=/src/MyComponent.ts

Steps to Reproduce the Bug or Issue

yarn start

Expected behavior

如何才是正确的做法,自定义节点组件中调用graph的一些方法?

Screenshots or Videos

image

Platform

  • OS: [e.g. macOS, Windows, Linux]
  • Browser: [e.g. Chrome, Safari, Firefox]
  • Version: [e.g. 91.1]

Additional context

No response

@xiazhaohui
Copy link

Demo好像有点问题

@BrickerZou
Copy link
Author

@BrickerZou
Copy link
Author

接上面的截图一样的问题
image

image
无限递归

@xiazhaohui
Copy link

我也遇到此类似问题,toJSON之后,使用JSON.stringify()序列化,报错爆栈。检查之后发现也是递归循环导致的

image

image

@BrickerZou
Copy link
Author

我也遇到此类似问题,toJSON之后,使用JSON.stringify()序列化,报错爆栈。检查之后发现也是递归循环导致的

image image

和你一样的问题,不知道哪出bug了

@xiazhaohui
Copy link

循环引用了

@BrickerZou
Copy link
Author

没找到在哪

@BrickerZou
Copy link
Author

你是怎么解决的

@xiazhaohui
Copy link

这个Graph对象的数据结构,貌似就是这样嵌套的
image

@xiazhaohui
Copy link

你是怎么解决的

目前只是异常捕获,还没做处理,还没定位到具体哪里

@BrickerZou
Copy link
Author

好兄弟,解决了后指点指点。

@xiazhaohui
Copy link

好兄弟,解决了后指点指点。

同是天涯沦落人,同指点。
感觉关键还是多理解一下API,看透了应该就知道问题出在哪里

@tonywu6
Copy link
Collaborator

tonywu6 commented Jun 24, 2022

Hello! React 组件配合 toJSON() 使用需要注意的事情以及一些解决方法,在文档的这里有提到:

Screen Shot 2022-06-24 at 5 30 32 PM

大概的建议做法是将 React 组件函数/类事先注册到全局 Graph 下,然后在 addNode 时使用字符串形式引用注册好的组件(具体见文档)

// 使用 Graph.registerNode(...) 方法将 React 组件注册到系统中。

Graph.registerNode('my-node', {
  inherit: 'react-shape',
  x: 200,
  y: 150,
  width: 150,
  height: 100,
  component: <MyComponent />
})

// 然后将节点的 shape 属性指定为注册的节点名称

graph.addNode({
  x: 40,
  y: 40,
  width: 100,
  height: 40,
  shape: 'my-node',
})

技术细节

具体来讲,发生堆栈溢出的原因在于 1) Graph 被作为 props 传给了 React 元素 + 2) Graph.toJSON() 输出的内容包含 React 元素 + 3) toJSON() 方法在 native JavaScript 中有特殊语义:

  1. 如 @SillyBoyXZH 提到的,React element 和 Graph 存在循环引用,这是因为 React element 会将 Graph 作为 props, 但是 Graph 又需要将这个 element 保存在内部的 model 里;
  2. 在 native JavaScript 中,JSON.stringify() 对任何 object 带有的 toJSON() 作特殊处理:如果一个 object 带有 toJSON(), 那么 JSON.stringify 使用这个方法返回的值进行序列化

Screen Shot 2022-06-24 at 5 47 42 PM

当我们进行 JSON.stringify(graph.toJSON()) 时:

stringify 对序列化的数据做递归处理
stringify 遇到自定义的 React 元素
→ 对 React 元素做递归处理
stringify 遇到 graph 对象(在 props 里)
stringify 调用 graph.toJSON()
stringify 对序列化的数据做递归处理
→ (...循环)

如果我们采用「事先注册元素」的方法,那么 React 元素就不会在 graph 内部保存(只是保存了它的名字),那么就不会出现这样的循环调用(当然,如果存在其它的循环引用,还是会出现堆栈溢出的).

@tonywu6 tonywu6 self-assigned this Jun 24, 2022
@tonywu6 tonywu6 added the type: documentation 文档 Issues related to project documentation and our official site label Jun 24, 2022
@xiazhaohui
Copy link

下周我试试。
之前写的时候也注意到这点了,要注册一下组件再使, 但是当时有侥幸心理,感觉不注册也能正常使用且没有任何报错等信息。

@tonywu6 如君所言,我再试试,兄弟你也试试 @BrickerZou ,有任何情况我来同步

@BrickerZou
Copy link
Author

BrickerZou commented Jun 24, 2022

下周我试试。 之前写的时候也注意到这点了,要注册一下组件再使, 但是当时有侥幸心理,感觉不注册也能正常使用且没有任何报错等信息。

@tonywu6 如君所言,我再试试,兄弟你也试试 @BrickerZou ,有任何情况我来同步

试了下,似乎没变化

@BrickerZou
Copy link
Author

BrickerZou commented Jun 24, 2022

不过我找到了原因,就是因为graph 被作为 props 传给了 React 元素
image
删去就没这个错误了。
但是如果不用prop传graph 那么我该如何调用graph的方法。
image

@xiazhaohui
Copy link

xiazhaohui commented Jun 28, 2022

so 注册之后还是使用toJSON()导出数据是吧

@BrickerZou
Copy link
Author

是的

@xiazhaohui
Copy link

xiazhaohui commented Jul 4, 2022

我是用第二个注册到系统的方法,试了下,也不行,还是有那种报错
@tonywu6

Graph.registerReactComponent('custom-trigger-cell', <TouchConditionGraphDom/>)
Graph.registerReactComponent('custom-judge-cell', <JudgeConditionGraphDom/>)
Graph.registerReactComponent('custom-execute-cell', <ExecuteActionGraphDom/>)

how about you? @BrickerZou

@NewByVector
Copy link
Contributor

@BrickerZou 不推荐在 react 组件内部再使用 graph,如果实在有必要的话,可以这样:

const graph = node.model.graph;

@x6-bot
Copy link
Contributor

x6-bot bot commented Jul 10, 2023

This thread has been automatically locked because it has not had recent activity.

Please open a new issue for related bugs and link to relevant comments in this thread.

@x6-bot x6-bot bot locked as resolved and limited conversation to collaborators Jul 10, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type: documentation 文档 Issues related to project documentation and our official site
Projects
None yet
Development

No branches or pull requests

4 participants