4

我有渲染 D3 树的 React 组件。代码片段如下所示。

componentDidMount()
{
    var mountNode = ReactDom.findDOMNode(this.tree);
    // Render the tree usng d3 after first component mount

    if (this.props.treeData)
    {
        renderTree(this.props.treeData, mountNode, this.props.nodeName);//renderTree is Javascript function
    }

}

contextmenu(node)
{
    this.setState = {
        style_popup: {
            top: d3.event.clientY,
            left: d3.event.clientX,
            position: 'absolute'
        },
        render_on_click: true
    }
}

render()
{
    // Render a blank svg node
    return (
        <div id="tree">
            <div id="tree-container" ref={(tree) =>
            {
                this.tree = tree;
            }}>

            </div>
            {
                (this.state.render_on_click) ? <PopUp popup_style={this.state.style_popup}/> : null
            }
        </div>
    );
}

在内部renderTree()不是React 函数)我有以下代码片段:

function renderTree(this.props.treeData, mountNode, this.props.nodeName)
{
//Some code.
.on('click',contextmenu);
}

我知道这是从 Js 调用React 的 contextmenu的错误方式,但是我将如何实现呢?我尝试使用参考

 <D3Tree ref={instance => { this.D3tree = instance; }}  treeData={this.props.treeData} />

但是 D3Tree 组件是从不同的文件中调用的,这就是我得到的原因

this.D3Tree 未定义。

我应该如何调用作为 React 函数的 contextmenu?

4

1 回答 1

0

在您导出组件的地方,例如

let instance = null;

class MyComponent extends React.Component {
    componentWillMount() {
        instance = this;
    }
    componentWillUnmount() {
        instance = null;
    }
}

export { MyComponent, instance as myComponentInstance }

在您能够使用import { myComponentInstance } from "file" 之后,它将是您的组件的 this,但前提是它一次是一个渲染实例,并且只有在检查条件为空的情况下。

这也不是正确的方法,你的代码会被支持它的人讨厌。

第二种方式 - 您可以在 React 组件之外的其他地方编写函数,例如:

const myFunction = (instance, someData) => {
}

class MyComponent extends React.Component {
    myFunction = (someData) => { myFunction(this, someData); }
}

无论如何,这两种方式都是反模式,但你可以实现你的目标。

于 2018-01-26T17:31:06.690 回答