我遇到了一个有趣的问题。我有一个父组件,它有一个对象数组,它们被传递给一个TreeView的子组件,这意味着它是递归的。我正在向孩子传递一个函数和一些其他道具,以及由孩子递归处理的对象数组。在子项的render函数中记录props时,在第一次渲染时所有的props都在那里,但是当递归函数移动到数组中的每个对象时,它“丢失”所有其他没有递归处理的道具。
当组件首次呈现props对象时:prop1,prop2,arrayOfObjects
当它重新呈现为递归时,子项中的props对象变为:arrayOfObjects。
prop1,prop2已经消失了。最终结果是我无法从子节点调用父节点中的函数,因此我无法根据单击树中的哪个节点来更新状态。我没有使用redux,因为这是一个样式指南 - 与我们的生产应用程序分开,仅适用于开发人员,而且很简单,所以如果可能的话我想从组件中处理所有状态。
还有一个问题 - 对象数组是我们的styleguide中文件的文件夹结构,我需要能够单击列表中的名称,并使用该文件的内容更新视图。当文件没有任何子节点时,这可以正常工作,但是当有子节点时,如果我单击父节点,则单击该子节点。我已经尝试了e.stopPropagation(),e.preventDefault()等但没有运气。提前致谢。
家长:
import React, {Component} from 'react'
import StyleGuideStructure from '../../styleguide_structure.json'
import StyleTree from './style_tree'
class StyleGuide extends Component {
constructor(props) {
super(props)
let tree = StyleGuideStructure
this.state = {
tree: tree
}
这是我想从孩子那里打电话的功能
setVisibleSection(nodeTitle) {
this.setState({
section: nodeTitle
})
}
render() {
return(
<TreeNode
className="class-name-here"
setVisibleSection={this.setVisibleSection.bind(this)}
node={this.state.tree}
/>
)
}
}
export default StyleGuide
这基本上就是我在孩子身上所做的事情,作为一个小提琴:
https://jsfiddle.net/ssorallen/XX8mw/
唯一的区别是在切换功能中,我试图在父级中调用setVisibleSection,但没有骰子。
答案 0 :(得分:1)
我认为我真的不明白你的第二个问题。你可以发一个显示问题的小提琴吗?
我认为你的第一个问题是你需要将道具传递给孩子们。我试图把你的例子转录成你的小提琴。您可以通过单击节点看到标题切换到节点的名称。
https://jsfiddle.net/hbjjq3zj/
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string str = value as string;
int idot = str.IndexOf(".");
int days = int.Parse(str.Substring(0,idot ));
int idotdot = str.IndexOf(":");
int ho = int.Parse(str.Substring(idot+1, idotdot-idot-1));
int newho = days * ho;
string res = newho.ToString() + str.Substring(idotdot);
return res;
}
/**
* Using React 15.3.0
*
* - 2016-08-12: Update to React 15.3.0, class syntax
* - 2016-02-16: Update to React 0.14.7, ReactDOM, Babel
* - 2015-04-28: Update to React 0.13.6
*/
class TreeNode extends React.Component {
constructor(props) {
super(props);
this.state = {
visible: true,
};
}
toggle = () => {
this.setState({visible: !this.state.visible});
this.props.setVisibleSection(this.props.node.title)
};
render() {
var childNodes;
var classObj;
if (this.props.node.childNodes != null) {
childNodes = this.props.node.childNodes.map((node, index) => {
return <li key={index}><TreeNode {...this.props} node={node} /></li>
});
classObj = {
togglable: true,
"togglable-down": this.state.visible,
"togglable-up": !this.state.visible
};
}
var style;
if (!this.state.visible) {
style = {display: "none"};
}
return (
<div>
<h5 onClick={this.toggle} className={classNames(classObj)}>
{this.props.node.title}
</h5>
<ul style={style}>
{childNodes}
</ul>
</div>
);
}
}
class ParentComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
visible: true,
};
}
toggle = () => {
this.setState({visible: !this.state.visible});
};
setVisibleSection(nodeTitle) {
this.setState({
title: nodeTitle
})
}
render() {
return (
<div>
Title: {this.state.title}
<TreeNode
node={tree}
setVisibleSection={this.setVisibleSection.bind(this)}
/>
</div>
);
}
}
var tree = {
title: "howdy",
childNodes: [
{title: "bobby"},
{title: "suzie", childNodes: [
{title: "puppy", childNodes: [
{title: "dog house"}
]},
{title: "cherry tree"}
]}
]
};
ReactDOM.render(
<ParentComponent />,
document.getElementById("tree")
);