从另一个组件获取观察到的变量并在更改时重绘

时间:2017-01-20 10:21:58

标签: reactjs mobx mobx-react

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

Node是一个组件,通过将xy坐标作为道具进行初始化:

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;

    ...
}

您可以拖放Nodelefttop值会相应更改。

Connection组件也被定义为@observer并且在我们需要连接的节点的props中传递绑定到可观察变量:

@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;
    }
    ...
}
然后,

NodesComponents会在父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组件,以便在其中一个节点传递给它时会收到通知&#34;更改&#34; (意味着它的lefttop已更改)以便我可以重绘节点之间的一条线?

基本上我有两个问题:

  1. 能够从left组件中获取top的{​​{1}}和Node个变量(以确定x,y和x的坐标; y我应该划一条线;;
  2. 仅在连接仅移动节点的Connection移动时仅重绘Connection

2 个答案:

答案 0 :(得分:0)

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

真的没有好的方法去听#34;更改另一个组件。这没关系,因为这将是一种反应模式。

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

当兄弟姐妹需要了解自己时,这总意味着你想要将属性控制提升一级。

答案 1 :(得分: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>
    )
  }
}

基本上,将商店保留在反应组件之外。