当状态更改时,react-graph-vis 中的 Graph 组件不会重新加载



我正在研究一个 React 组件,它包装了 react-graph-vis 的Graph组件。我的组件应该呈现某个图形,并提供一个按钮来向图形中添加节点。

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

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/>组件。

我错过了什么?

您应该始终将 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),如果 prop 的引用graph没有改变,那么组件就不会更新。这可以解释为什么你的按钮更新而Graph没有。

最新更新