我正在调查facebook的react.js,发现它到目前为止非常酷。我试图创建一个简单的文件夹结构,您可以在其中打开和关闭每个文件夹。 我的结构看起来像这样
<Folder>
<Header/>
<Content/>
</Folder>
单击标题会导致文件夹隐藏/显示其内容。这很容易通过国家完成。
但现在我想拥有多个文件夹和一个“全部切换”按钮。如何让按钮切换所有孩子而不会造成大杂乱?我使用refs来解决它们,但我认为这是一种不好的做法,因为the Documentation状态:
...你的第一个倾向通常是试图在你的应用程序中使用refs“让事情发生”......
...考虑组件层次结构中应该拥有哪个状态。通常,很明显,“拥有”该状态的适当位置在层次结构中处于更高级别。
我创建了一个Fiddle来演示整个事情。它工作正常,但我认为这不是一个很好的解决方案。
PS(奖金问题): 是不是通过不渲染来隐藏内容(比如在小提琴中完成),或者只是添加'display:none;' styletag?
答案 0 :(得分:2)
在reactjs中引用儿童的正确方法 - &gt;不要引用儿童来查询他们的状态。如果您需要从父级查询该状态,请将该状态放在父级中,并将状态作为道具注入子级中。
以下是您的代码重做: http://jsfiddle.net/t5fwn/7/
/** @jsx React.DOM */
var initialState = {
"folders": [
{
"name": "folder1",
"open": false,
"files": [{
"text": "content1 1"
}]
},
{
"name": "folder2",
"open": false,
"files": [{
"text": "content2 1"
}, {
"text": "content2 2"
}]
}
]
};
var Folder = React.createClass({
render: function() {
var items = [];
if( this.props.folderData.open ){
this.props.folderData.files.forEach(function(file) {
items.push( <div className="itemBox">{file.text}</div>);
});
}
return (
<div className="items_directory">
<div className="folder_header" onClick={this.props.onFolderClick}>{this.props.folderData.name}</div>
<div className="folder_content">
{items}
</div>
</div>
);
}
});
var FoldersManager = React.createClass({
getInitialState: function() {
return this.props.initialState;
},
render: function(){
var self = this;
var folderComponents = this.state.folders.map(function(folder,folderIndex) {
var onFolderClick = function() {
self.toggleFolder(folderIndex);
};
return <Folder folderData={folder} onFolderClick={onFolderClick}/>;
});
return (
<div>
<button onClick={this.toggleAll}>Toggle All</button>
<div>
{folderComponents}
</div>
</div>
);
},
toggleFolder: function(folderIndex) {
var newState = this.state;
newState.folders[folderIndex].open = !newState.folders[folderIndex].open;
this.setState(newState);
},
toggleAll: function(){
var newState = this.state;
var newOpenToSet = this.isAllFoldersOpen() ? false : true;
newState.folders.forEach(function(folder) {
folder.open = newOpenToSet;
});
this.setState(newState);
},
isAllFoldersOpen: function() {
return this.countFoldersOpen() == this.state.folders.length;
},
countFoldersOpen: function() {
var i = 0;
this.state.folders.forEach(function(folder) {
if ( folder.open ) i++;
});
return i;
}
});
React.renderComponent(<FoldersManager initialState={initialState} />, document.body);
最好有一种管理所有文件夹状态打开/关闭的管理器组件。 Folder组件可以简单地用于呈现文件夹,但不能用于管理文件夹的状态,或者在全局toggleAll
操作中,您必须“查询”子组件以了解其状态。
PS(奖金问题):我认为不呈现未显示的内容会更优雅。但是出于性能原因,如果隐藏/显示状态经常变化,最好使用display : none;
:它会产生相同的视觉效果,但DOM差异会更小。除非您在未呈现隐藏元素的情况下发现性能问题,否则不要对此进行优化。