引用儿童反应的正确方法 - >不要引用儿童来查询他们的状态。如果您需要从父项查询该状态,请将该状态置于父项中,并在子项中注入状态作为道具。
这里是你的代码返工: 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组件可以简单地用于渲染文件夹,但不用于管理文件夹的状态,或者在您的全局操作中,您将不得不“查询”子组件以了解其状态。
PS(奖金问题):我认为这是更优雅不渲染不显示的内容。但出于性能方面的原因,如果隐藏/显示状态频繁更改,最好使用display : none;
:它会产生相同的视觉效果,但DOM差异会更小。除非您看到不呈现隐藏元素的性能问题,否则不要优化它。
感谢您的回答!我怀疑这一点。我只是认为将切换状态保存到文件夹本身会很好,因为我认为它属于那里。但你是对的,嵌套所有的州,然后让他们互动似乎是一个坏概念。 – eyeballz
@eyeballz如果只有来自文件夹组件的事件可以更改此状态,则文件夹打开/关闭状态属于该文件夹。在你的例子中'toggleAll'事件不是来自文件夹组件,而是来自另一个。认为“哪些组件可以改变哪个应用程序状态”是一个好主意。然后,您可以找到最近的共同父母,并将此状态置于此处,以便您不必在任何地方查询儿童组件。 –