javascript - 在 reactjs 中引用子项的正确方法

标签 javascript reactjs

我正在研究 facebook 的 react.js,发现它到目前为止非常酷。我尝试制作一个简单的文件夹结构,您可以在其中打开和关闭每个文件夹。 我的结构看起来像这样

<Folder> <Header/> <Content/> </Folder>

单击标题会导致文件夹隐藏/显示其内容。这很容易通过国家来完成。

但现在我想要多个文件夹和一个“全部切换”按钮。如何在不造成困惑的情况下获得切换所有子项的按钮?我使用 refs 来解决它们,但我认为这是一种不好的做法 the Documentation状态:

...your first inclination is usually going to be to try to use refs to "make things happen" in your app...

...think about where state should be owned in the component hierarchy. Often, it becomes clear that the proper place to "own" that state is at a higher level in the hierarchy.

我创建了一个 Fiddle展示整个事情。它正在运行,但我认为这不是一个很好的解决方案。

PS(奖金问题): 是通过不渲染内容来隐藏内容(就像在 fiddle 中完成的那样)还是只添加“显示:无;”更好?样式标签?

最佳答案

在 reactjs 中引用 child 的正确方法 -> 不要引用 child 来查询他们的状态。如果您需要从父级查询该状态,请将该状态放入父级并将该状态作为 props 注入(inject)子级。

这是您修改后的代码: 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 差异会更轻。除非您发现不渲染隐藏元素的性能问题,否则不要对此进行优化。

关于javascript - 在 reactjs 中引用子项的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22223337/

相关文章:

javascript - 自动关闭后不再显示 Bootstrap 警报对话框

javascript - 如何打印 html 表格中仅一个单元格关联的结果集

javascript - 使用 Node SSL 将客户端证书设为可选(rejectUnauthorized : true doesn't do it? )

javascript - 使用纯组件模式测试 Gatsby 的静态查询时,你能做到完全覆盖吗?

node.js - 如何在我的 react 应用程序中运行弹出?

"class"内的 JavaScript Image 对象

javascript - 将类添加到同位素中的过滤项目和隐藏项目。按钮不是复选框

reactjs - Webpack 构建与 React-scripts 构建

javascript - 打开其他下拉菜单时 react 关闭下拉菜单

javascript - 如何在 JSX 中添加 If...Else 语句而不需要 2 个 if 语句?