React.js:组合组件以创建选项卡

Posted

技术标签:

【中文标题】React.js:组合组件以创建选项卡【英文标题】:React.js: Composing components to create tabs 【发布时间】:2014-01-19 07:00:31 【问题描述】:

我正在尝试制作一个标签组件。 TabsSwitcher 和 TabsPanel 必须是单独的组件,以便它们可以在 DOM 中的任何地方使用,例如TabsSwitcher 后面不一定要跟 TabsPanel。

为了让它工作,我需要以某种方式连接这些组件。此外,TabsSwitcher 必须能够告诉 TabsPanel 何时单击了选项卡。

/** @jsx React.DOM */

var TabsExample = React.createClass(
    render: function() 
        var tabs = [
            title: 'first', content: 'Content 1',
            title: 'second', content: 'Content 2'
        ];
        return <div>
            <TabsSwitcher items=tabs/>
            <TabsContent items=tabs/>
        </div>;
    
);

var TabsSwitcher = React.createClass(
    render: function() 
        var items = this.props.items.map(function(item) 
            return <a onClick=this.onClick>item.title</a>;
        .bind(this));
        return <div>items</div>;
    ,
    onClick: function(e) 
        // notify TabsContent about the click
    
);

var TabsContent = React.createClass(
    render: function() 
        var items = this.props.items.map(function(item) 
            return <div>item.content</div>;
        );
        return <div>items</div>;
    
);

React.renderComponent(
    <TabsExample/>,
    document.body
);

最好的方法是什么?


解决方案:http://jsfiddle.net/NV/5YRG9/

【问题讨论】:

【参考方案1】:

React 文档在“Communicate Between Components”和“Multiple Components”中详细介绍了这一点。要点是父母应该将一个函数作为道具传递给孩子,孩子应该在需要时将该函数作为回调调用:

var TabsExample = React.createClass(
    handleTabClick: function(item) 
        // Do something with item, maybe set it as active.
    ,
    render: function() 
        var tabs = [
            title: 'first', content: 'Content 1',
            title: 'second', content: 'Content 2'
        ];
        return <div>
            <TabsSwitcher items=tabs onTabClick=this.handleTabClick/>
            <TabsContent items=tabs/>
        </div>;
    
);

var TabsSwitcher = React.createClass(
    render: function() 
        var items = this.props.items.map(function(item) 
            return <a onClick=this.onClick.bind(this, item)>item.title</a>;
        .bind(this));
        return <div>items</div>;
    ,
    onClick: function(item) 
        this.props.onTabClick(item);
    
);

对于TabsContent 组件,您应该将tabs 移动到TabsExample 状态,以便React 可以在它们更改时自动为您重新渲染。由于 TabsSwitcherTabsContent 在 render 方法中传递了选项卡,React 知道它们依赖于选项卡,并且会在状态更改时重新渲染:

var TabsExample = React.createClass(
    getInitialState: function() 
        return 
            activeTabId: 1,
            tabs: [
                title: 'first', content: 'Content 1', id: 1,
                title: 'second', content: 'Content 2', id: 2
            ]
        ;
    ;
    handleTabClick: function(item) 
        // Call `setState` so React knows about the updated tab item.
        this.setState(activeTabId: item.id);
    ,
    render: function() 
        return (
            <div>
                <TabsSwitcher items=this.state.tabs
                              activeItemId=this.state.activeTabId
                              onTabClick=this.handleTabClick/>
                <TabsContent items=this.state.tabs
                             activeItemId=this.state.activeTabId/>
            </div>
        );
    
);

【讨论】:

"// 对项目做一些事情,也许将其设置为活动。"。如何在相应的 TabsContent div 上设置“活动”类并删除以前活动的类? "如何在对应的 TabsContent div 上设置“活动”类并移除之前的活动类?实际上对于 React 来说是一个奇怪的措辞;这就是 jQuery-modify-the-DOM 的心态。对于 React,问题是“如何根据选项卡状态设置“活动”类?”。我将在我的代码中添加一个示例。 现在查看答案中的底部代码示例。 TabsExample 组件跟踪活动选项卡 ID。 是的,这与我提出的解决方案非常相似:jsfiddle.net/NV/5YRG9。我将其添加到问题中,但我认为您没有注意到。 只是一个问题@ssorallen:你为什么不在你的代码 sn-p 中普遍使用变量名“tabs”?您将两个名词“标签”和“项目”用于一件事。

以上是关于React.js:组合组件以创建选项卡的主要内容,如果未能解决你的问题,请参考以下文章

React.js Material-UI:以编程方式隐藏和显示选项卡

当我在 React.js 中更改活动页面时,如何将我的数据保存在页面中?

如何在 Vue 3 中访问 $children 以创建选项卡组件?

我可以创建单例 vaadin 组合框组件吗?

使用 React.js 在选项卡上切换类

添加重新激活验证器以使用选项卡中子组件中的输入形成