我在typescript中编写了一个简单的树视图,使用 react 来呈现 DOM。
每个节点都必须遵循简单的界面。
interface INode {
label: string;
children: INode[];
}
然后树被描述为:
var tree = {
label: "root",
children: [
{
label: "node 1",
children: [
{
label: "node 1.0",
children: []
},
{
label: "node 1.1",
children: []
}
]
},
{
label: "node 2",
children: []
}
]
};
很简单的。组件现在也非常简单。对于我拥有的节点:
class Node extends React.Component<INode, void>{
render() {
console.log(`Rendering ${this.props.label}`);
var list = this.props.children.map((node, i) => <li key={i}><Node {...node}/></li>);
return (
<div>
<span>{this.props.label}</span>
{this.props.children.length > 0 ? <ul>{list}</ul> : ""}
</div>
);
}
}
对于树的根,我使用 state 而不是 props。但是 1 秒后我刷新了状态。但是状态本身并没有改变:
class Root extends React.Component<void, INode>{
constructor() {
super();
this.state = tree;
}
componentWillMount() {
setTimeout(() => {
this.setState((prevState: INode, props: void) => {
console.log(`Updating state of ${this.state.label}`);
return prevState;
});
}, 1000);
}
render() {
var list = this.state.children.map((node, i) => <li key={i}><Node {...node} /></li>);
return (
<div>
<span>{this.state.label}</span>
{this.state.children.length > 0 ? <ul>{list}</ul> : ""}
</div>
);
}
}
要运行此应用程序,只需以下几行代码:
ReactDOM.render(
<Root/>,
document.getElementById("app")
);
呈现的 html 看起来应该如此。我现在的问题是当我查看浏览器控制台时,我看到
渲染节点 1
渲染节点 1.0
渲染节点 1.1
渲染节点 2
更新根状态
渲染节点 1
渲染节点 1.0
渲染节点 1.1
渲染节点 2
整个树被重新渲染(进入虚拟 DOM),而状态的值和孩子的props没有改变。
假设渲染过程将非常复杂且耗时。是否有可能停止将孩子重新渲染到虚拟 DOM 中?