如何使用Cytoscape.js创建功能性React组件?

时间:2020-08-09 16:50:36

标签: reactjs react-hooks cytoscape.js

我正在使用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对象(并修改其节点和元素)?

1 个答案:

答案 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不会显示并失败,直到它具有正确呈现所需的内容为止。