2017-02-14 153 views
0

我遇到了一个有趣的问题。我有一个父组件,它有一个对象数组传递给一个TreeView的子组件,这意味着它是递归的。我将一个函数和一些其他道具传递给子对象,以及由子对象递归处理的对象数组。当在孩子的渲染函数中记录道具时,在第一次渲染时,所有道具都在那里,但是随着递归函数移动数组中的每个对象,它会丢失所有其他没有被递归处理的道具。如何将道具传递给递归子组件并保留所有道具

当组分首先渲染道具对象是:为prop1,PROP2,arrayOfObjects

由于它重新呈现为递归正在发生,道具对象在子变为: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/

唯一的区别是在里面的切换fu我试图在父母中调用setVisibleSection,但没有骰子。

下面是该道具控制台的照片时,该组件最初呈现,然后递归后: enter image description here

+0

我已经添加上述表示递归期间对象被 '排空' 道具的图像。递归之后,我不再能够访问setVisibleSection函数。剩下的唯一道具是节点道具。如果我没有将节点道具传递给孩子,所有的道具都保持不变。 –

回答

1

我不认为我真的能理解你的第二个问题。你可以张贴小提琴来展示这个问题吗?

我认为你的第一个问题是你需要将道具传递给孩子。我试图将你的例子转录到你的小提琴上。您可以通过单击节点来查看标题切换到节点的名称。

https://jsfiddle.net/hbjjq3zj/

/** 
 
* 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 = { 
 
    \t visible: true, 
 
    }; 
 
    } 
 
    
 
    toggle =() => { 
 
    this.setState({visible: !this.state.visible}); 
 
    this.props.setVisibleSection(this.props.node.title) 
 
    }; 
 
    
 
    render() { 
 
    \t 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 = { 
 
    \t visible: true, 
 
    }; 
 
    } 
 
    
 
    toggle =() => { 
 
    this.setState({visible: !this.state.visible}); 
 
    }; 
 
    setVisibleSection(nodeTitle) { 
 
    this.setState({ 
 
     title: nodeTitle 
 
    }) 
 
    } 
 
    render() { 
 
    return (
 
    \t <div> 
 
     \t Title: {this.state.title} 
 
     \t <TreeNode 
 
     \t 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") 
 
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

+0

谢谢你看看这个。在描述中,我将道具传给了孩子们。我试图将该setVisibleSection函数作为道具传递给孩子。出于某种原因,它被递归消灭了。它在这里的例子中起作用,但是在我的机器的控制台中,我可以看到对象发生了变化。第一次呈现的内容不是当它完成递归时的情况。我会张贴一张照片。离奇。 –

+0

我看到您将所有道具传递给正在递归的子组件。解决了这个问题。我将它们传递给孩子,但不传递给孩子在地图内对自身的引用。谢谢! –