我正在尝试使用react组件递归地构造树(json对象)的一些SVG。每个节点(树的节点)组件都返回其他节点(和边),直到不再有子节点为止。这棵树在我的屏幕上呈现得非常完美。
现在我想用一个函数来计算所有的叶节点,我通过道具传递给所有的节点。当一个节点没有子节点时,它会调用其构造函数中的函数。有了这个功能,我想使用this.set状态增加我主要组件的this.state.count叶。这个函数被调用的频率和我的树中有叶子节点一样高(我正在用console.log检查它)。对于每个叶节点,函数被调用,但我的状态不更新。
我的主要组成部分:
import React, { Component } from 'react';
import SpecNode from './graphicTreeComponents/SpecNode.js';
class GraphicController extends Component {
constructor(props){
super(props);
this.incLeafs = this.incLeafs.bind(this);
this.state = ({
u: {key: "0", x: 100, y: 0, k:
[
{key: "1", x: 40, y: 100, k: null},
{key: "2", x: 160, y: 100, k: null}
]
},
countLeafs: 0
})
}
incLeafs(){
console.log("leafs++");
this.setState({countLeafs: this.state.countLeafs + 1});
console.log(this.state.countLeafs);
}
render(props){
return (
<div className="GraphicController">
<SpecNode {...this.state.u} incLeafs={this.incLeafs}/>
</div>
);
}
}
export default GraphicController;
和我的节点组件:
import React, { Component } from 'react';
import Edge from './Edge.js';
import SpecNode2 from './SpecNode.js';
class SpecNode extends Component{
constructor(props){
super(props);
if(!this.props.k){
this.props.incLeafs();
}
}
render(props){
return(
<svg>
{this.props.k ?
this.props.k.map(e =>
<svg>
<Edge x1={this.props.x} y1={this.props.y} x2={e.x} y2={e.y} />
<SpecNode2 {...e} incLeafs={this.props.incLeafs}/>
<circle cx={e.x} cy={e.y} r={5} fill={"lightgrey"} />
<text fontSize={7} x={e.x-2} y={e.y+3} fill="black">{e.key}</text>
</svg>
)
:
null
}
</svg>
);
}
}
export default SpecNode;
有什么我错过的吗?
非常感谢。
您的方法this.incLeafs未绑定到父组件。因此,当它运行时,this
并不意味着子节点调用该方法时的GraphicController
。
任何一个
A) 更改将父类上的方法写入arrow函数的方式,如下所示:incLeafs=()=
B) 在某个点手动绑定method方法,例如使用
this.incLeafsHandler=this.incLeafs.bind(this)
,然后将this.incLeafsHandler
作为incLeaf回调传递给SpecNode。((我非常不喜欢这个解决方案,但这只是我的偏好。)
C),在道具中作为箭头函数向下传递(如
箭头函数总是保留
this
,无论它是什么,当箭头函数被声明。(备选方案A和C)
普通函数将根据调用它们的位置更改
this
,除非您使用原始方法的绑定副本。(备选案文B)
你确定leafCount没有更新吗?setState是异步的,但需要回调。您的console.log可能在状态更新之前发生。你应该试试像。。。
incLeafs(){
console.log("leafs++");
this.setState({countLeafs: this.state.countLeafs + 1}, () => {
console.log(this.state.countLeafs);
});
}
在主组件中,初始化状态时不需要括号。
this.state = {
u: {key: "0", x: 100, y: 0, k:
[
{key: "1", x: 40, y: 100, k: null},
{key: "2", x: 160, y: 100, k: null}
]
},
countLeafs: 0
}
您还可以尝试将您的函数调用移动到SpecNode组件中的组件
constructor(props){
super(props);
}
componentDidMount() {
if(!this.props.k){
this.props.incLeafs();
}
}
我想用XSLT转换XML文档。按名称和属性匹配的节点及其子节点应嵌套/移动到新节点中。 从转变 到 但是我的XSLT工作不好。您有什么提示吗,XSLT文件有什么问题? 非常感谢你 安德烈亚斯 我的XSLT 输出: 我的源XML文件 我希望在转换后的输出中将v:data节点及其子节点嵌套到一个新节点中。但只有属性名为“Custon”的v:data节点。转换后的XML文档应该如下所示 如果我从XSLT
我想从父节点复制到子节点。我真的不确定这是如何实现的。 我的源xml 我想得到输出为 我想要XSLT1.0中的解决方案。 我想将这些节点复制到子节点 谢谢。
我需要将子元素复制到父元素中。 输入 期望输出 我尝试的内容(输出与输入保持相同): 我肯定会错过一些非常简单的事情。子元素与父元素具有相同的名称,这应该不是问题?
我正在用flexbox做实验,并创建了这个布局。我试图让中间写着“嘿”的白色方框成为父方框的90%宽度/高度,但百分比似乎不会影响它。(我把它设置为100px/100px目前工作) 这很奇怪,因为父节点在检查时有一个定义的宽度/高度。 有人能告诉我如何实现吗?(此外,对我如何使用flexbox的一般批评也很赞赏) http://jsfiddle.net/yv3Lw5gy/1/ 相关类别:
如果我没弄错的话,树通常是一个列表,其中的元素按特定顺序排列。孩子们不在他们自己的子列表中,他们都在同一个列表中。 所以,我试图创建一个Tree类,其中包含TreeNodes(类)使用Tree类中的List。 我如何跟踪父母/孩子/叶子?如果父母“父母1”,有两个孩子“孩子A”和“孩子B”,我如何将他们联系在一起?