当状态发生变化时,react-graph-vis中的Graph组件不会重新加载

时间:2017-03-17 11:18:05

标签: reactjs vis.js

我正在处理一个包含react-graph-vis Graph组件的React组件。我的组件应该呈现某个图形,并提供一个按钮,用于向图形添加节点。

我所做的简化版本是以下组件,它呈现(单个节点)图形和按钮。单击该按钮应该向图表添加第二个节点。

class GraphWrapper extends React.Component {
   constructor(props) {
      var graph = {nodes: [{id: 1, label: '1'}], edges: []};
      this.state = {
         options: {},
         graph: graph
      };
   }

   addNode() {
      var graph = this.state.graph;
      graph.nodes.push({id: 2, label: '2'});
      this.setState({});
   }

   render() {
      return <div>
                <Graph graph={this.state.graph}, options={this.state.options}/>
                <button onClick={this.addNode.bind(this)}>Add Node</button>
             </div>;
   }
}

初始图表正在正确呈现。此外,单击按钮可以按预期更改状态。但是,图形可视化不会发生变化,第二个节点也不会显示,尽管状态发生了变化,似乎<Graph/>组件仍未被重新渲染。

我错过了什么?

1 个答案:

答案 0 :(得分:4)

您应该始终将React状态视为不可变。在您的情况下,您正在改变状态,这意味着即使数组内容已更改,引用this.state.graphthis.state.graph.nodes也是相同的。

addNode的更好版本:

 addNode() {
      var nodesCopy = this.state.graph.nodes.slice(); // this will create a copy with the same items
      nodesCopy.push({id: 2, label: '2'});
      this.setState({ graph: {nodes: nodesCopy, edges: []};);
   }

请注意,由于您更改了nodes引用,因为它现在指向一个新数组,因此您不得不将其级联,将每个引用更改为状态的根目录。

修改

在这个答案的前一个版本中,我暗示如果状态“引用”没有改变,React不会重新渲染。这是不正确的。 setState将永远导致重新投降。 ,如果他们收到的道具没有更改,则各个组件可能会选择进行更新。

关于你的评论@snakile,你所描述的最可能的原因是Graph组件以这样的方式实现了shouldComponentUpdate(nextProps, nextState),如果道具graph的引用没有改变,那么组件不会更新。这可以解释为什么Graph没有更新按钮的原因。