0

在我的项目中,我有两个节点(svg 框)和它们之间的连接(箭头)。

Node 是一个组件,它通过传递xy坐标作为 props 来初始化:

let nodes = [];
nodes.push(<Node key={0} x={50} y={100} />);
nodes.push(<Node key={1} x={300} y={100} />);

现在我有一个Connection组件,它应该有两个参数:一个Node连接自和一个Node连接到:

let connections = [];
connections.push(<Connection key={1} from={nodes[0]} to={nodes[1]} /> );

Node被定义为@observer并且有两个可观察的属性

@observer
export default class Node extends React.Component {

    @observable left = 6;
    @observable top = 8;

    ...
}

您可以拖放Nodeleft并且top值将相应更改。

Connection组件也被定义为@observer并传入我们需要连接的节点的道具绑定到可观察变量:

@observer
export default class Connection extends React.Component {

    @observable node_from;
    @observable node_to;

    componentDidMount() {
        this.node_from = this.props.from;
        this.node_to = this.props.to;
    }
    ...
}

Nodes然后Components在 parent 的render()方法中呈现,如下所示:

render() {
    let nodes = [];
    nodes.push(<Node key={0} x={50} y={100} />);
    nodes.push(<Node key={1} x={300} y={100} />);

    let connections = [];
    connections.push(<Connection key={1} from={nodes[0]} to={nodes[1]} /> );

    return (
        <div>
            <svg width={600} height={400}>
                {connections}
                {nodes}
            </svg>
        </div>
    );
}

现在我的问题是我无法弄清楚如何修改我的Connection组件,因此每当传递给它的节点之一“更改”(意味着它left或被top更改)时它都会收到通知,以便我可以在节点之间重新绘制一条线?

基本上我有两个问题:

  1. 能够从内部组件中获取lefttop变量(确定从 x;y 到什么 x;y 我应该画一条线的坐标);NodeConnection
  2. Connection仅在移动时重绘 a ,Node仅连接正在移动的节点。
4

2 回答 2

0

对于刚进入 React 世界的新人来说,这是一个常见的问题。

真的没有很好的方法来“监听”另一个组件的变化。没关系,因为这将是一种反模式反应。

相反,您想要做的是将Node组件外部的 x 和 y 坐标的控件移动到父组件中。这个父组件将控制两个节点的位置,并Connection根据它们的位置更新它们之间的箭头。

当兄弟姐妹需要了解他们自己时,这总是意味着您希望将属性控制上移一级。

于 2017-01-20T10:39:42.283 回答
0

我无法将此添加为评论,但请尝试关注。

class NodeStore {
  constructor(x,y){
    extendObservable(this, {x, y});
  }
}

class ConnectionStore {
  constructor(source, target){
    extendObservable(this, {source, target});
  }
}

@observer
class Node extends React.Component {
  render(){
    ...
  }
}

@observer 
class Connection extends React.Component {
  render(){
    ...
  }
}

@observer 
class Paint extends React.Component {
  @observable connections = [];
  @observable nodes = [];
  render(){
    const {connections, nodes} = this;
    return (
      <svg width={600} height={400}>
        {connections.map( connection => <Connection {...connection}/> )}
        {nodes.map( node => <Node {...node}/>)}
      </svg>
    )
  }
}

基本上,将 store 放在 react 组件之外。

于 2017-04-27T07:06:36.417 回答