我正在使用Cytoscape.js和React。我有一个功能强大的GraphComponent,用于接收用于渲染Cytoscape图的元素列表以及希望创建动画的节点列表。
我的问题是我无法弄清楚如何持久存储“ cy”对象,以便以后可以访问它。具体来说,我想向路径中的节点添加一个类。
const MyComponent = ({ myElements, path }) => {
useEffect(() => {
const cy = {
...
elements: myElements
...
}
}, []);
useEffect(() => {
// This fails since 'cy' is undefined
cy.$id("A").addClass("highlighted");
}, [path]);
return (
<div id="cy" />
);
}
想法1:创建一个变量“ cy”,然后可以在useEffect中将其值设置为
。问题:初始渲染后,“ cy”的值丢失了
const MyComponent = ({ myElements, path }) => {
let cy;
useEffect(() => {
cy = {
...
elements: myElements
...
}
}, []);
useEffect(() => {
// This fails since 'cy' is undefined
cy.$id("A").addClass("highlighted");
}, [path]);
return (
<div id="cy" />
);
}
想法2:将cy保存为状态。
问题:Cy未正确初始化
const MyComponent = ({ myElements, path }) => {
const [cy, setCy] = useState({});
useEffect(() => {
setCy({
...
elements: myProp
...
});
}, []);
useEffect(() => {
cy.$id("A").addClass("highlighted");
}, [path]);
return (
// This fails since cy is not initialized to a cytoscape object when component mounts
<div id="cy" />
);
}
问题是,如何在反应功能组件内部创建和访问cytoscape对象(并修改其节点和元素)?
答案 0 :(得分:2)
您通常不希望在状态下存储道具,因为您已经将道具存储在其他位置。如果您通过道具传递cy的数据,则只需使用道具。
通常,如果您尝试根据外部更改来保持状态更新,则需要向useEffect
挂钩添加依赖项。空数组表示该效果在安装时只能运行一次。
请参阅文档以获取良好的教程,但通常它的工作原理如下:
useEffect(()=> {
setSomeState(/* set state */)
}, [someValue])
如果someValue
保持不变,则该效果将不会重新运行。如果更改,则该效果将在下次渲染时运行(由于属性或状态更改)。
同样,如果数据是通过道具输入的,则不要将其设置为状态。如果您想跟踪基于该道具的组件内部的某些内容,则对道具依赖的useEffect将为您解决该问题。
状态是,您可以在其中保存渲染之间的数据。如果问题在于您不应该渲染,因为一个值在mount上不存在(而是在另一个渲染中),则将其包装在一个表达式中,例如,
{someValueOrExpression ? <div id="cy" /> : <div>Empty State</div>}
或
{someValueOrExpression && <div id="cy" />}
这样,div不会显示并失败,直到它具有正确呈现所需的内容为止。